home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / shells / cshel500 / part04 < prev    next >
Encoding:
Internet Message Format  |  1991-03-03  |  64.4 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i030: CShell 5.00 - alternative command interface, Part04/06
  4. Reply-To: <umueller@iiic.ethz.ch>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i030@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v91i027@ab20.larc.nasa.gov>
  8. Date: 03 Mar 91 21:56:06 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: <umueller@iiic.ethz.ch>
  14. Posting-number: Volume 91, Issue 030
  15. Archive-name: shells/cshell-5.00/part04
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 6)."
  24. # Contents:  comm1.c execom.c
  25. # Wrapped by tadguy@ab20 on Sun Mar  3 16:56:00 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'comm1.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'comm1.c'\"
  29. else
  30. echo shar: Extracting \"'comm1.c'\" \(30286 characters\)
  31. sed "s/^X//" >'comm1.c' <<'END_OF_FILE'
  32. X/*
  33. X * COMM1.C
  34. X *
  35. X * Matthew Dillon, August 1986
  36. X *
  37. X * Version 2.07M by Steve Drew 10-Sep-87
  38. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  39. X * Version 5.00L by Urban Mueller 17-Feb-91
  40. X *
  41. X */
  42. X
  43. X#include "shell.h"
  44. X
  45. X/* comm1.c */
  46. Xstatic void display_file(char *filestr);
  47. Xstatic char *myfgets(char *buf, int buflen, struct __stdio *file);
  48. Xstatic int search_file(char *s);
  49. Xstatic int quicksearch(char *name, int nocasedep, char *pattern);
  50. Xstatic int rm_file(char *file);
  51. Xstatic void setsystemtime(struct DateStamp *ds);
  52. Xstatic int found( char *lstart, int lnum, int loffs, char *name, char left );
  53. Xstatic void recurse(char *name, int (*action)(char *));
  54. Xstatic void recurse2( char *name, void (*action)(FIB *));
  55. X
  56. Xextern int has_wild;
  57. X
  58. Xint
  59. Xdo_sleep( void )
  60. X{
  61. X    int i;
  62. X
  63. X    if (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i--) Delay(50);
  64. X    return 0;
  65. X}
  66. X
  67. Xint
  68. Xdo_protect( void )
  69. X{
  70. X    static char flags[]="DEWRAPSH";
  71. X    char *s, *p;
  72. X    long setmask=0, clrmask=0xFF, mask;
  73. X    int  i, mode=0, stat;
  74. X    struct DPTR *dp;
  75. X
  76. X    for (s=strupr(av[--ac]); *s; s++) {
  77. X        if (*s=='=') { mode=0; continue; }
  78. X        if (*s=='+') { mode=1; clrmask=FIBF_ARCHIVE; continue; }
  79. X        if (*s=='-') { mode=2; clrmask=FIBF_ARCHIVE; continue; }
  80. X
  81. X        if (p=index(flags, *s)) {
  82. X            if( mode==0 ) setmask|= 1<<(p-flags), clrmask=0xFF;
  83. X            if( mode==1 ) setmask|= 1<<(p-flags);
  84. X            if( mode==2 ) clrmask|= 1<<(p-flags);
  85. X        } else
  86. X            ierror(av[ac],500);
  87. X    }
  88. X
  89. X    for (i=1; i<ac; i++) {
  90. X        if( (dp=dopen(av[i],&stat))) {
  91. X            mask = dp->fib->fib_Protection ^ 0x0F;
  92. X            mask&=~clrmask;
  93. X            mask|= setmask;
  94. X            dclose(dp);
  95. X            if( !SetProtection( av[i], mask ^ 0x0F))
  96. X                pError(av[i]);
  97. X        } else
  98. X            pError(av[i]);
  99. X    }
  100. X    return 0;
  101. X}
  102. X
  103. Xint
  104. Xdo_filenote( void )
  105. X{
  106. X    struct DPTR *dp;
  107. X    char *note;
  108. X    int i, stat;
  109. X
  110. X    if( options&1 ) {
  111. X        for( i=1; i<ac && !dobreak(); i++ )
  112. X            if( dp=dopen( av[i], &stat )) {
  113. X                printf( "%-12s %s\n", av[i],dp->fib->fib_Comment );
  114. X                dclose( dp );
  115. X            }
  116. X    } else {
  117. X        note=av[--ac];
  118. X        for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  119. X    }
  120. X    return 0;
  121. X}
  122. X
  123. Xint
  124. Xdo_cat( void )
  125. X{
  126. X    FILE *fi;
  127. X    int lctr, i;
  128. X    char buf[256];
  129. X
  130. X    prepscroll(0);
  131. X    if (ac<=1) {
  132. X        if (has_wild) { printf("No files matching\n"); return 20; }
  133. X        lctr=0;
  134. X        while (fgets(buf,256,stdin) &&
  135. X               !dobreak()) {
  136. X            if (options) printf("%4d ",++lctr);
  137. X            quickscroll();
  138. X            fputs(buf,stdout);
  139. X        }
  140. X    } else {
  141. X        for (i=1; i<ac; i++)
  142. X            if (fi = fopen (av[i], "r")) {
  143. X                lctr=0;
  144. X                while (fgets(buf,256,fi) && !dobreak()) {
  145. X                    if (options&1) printf("%4d ",++lctr);
  146. X                    quickscroll();
  147. X                    printf("%s",buf);
  148. X                }
  149. X                fclose (fi);
  150. X            } else
  151. X                pError(av[i]);
  152. X    }
  153. X    return 0;
  154. X}
  155. X
  156. X
  157. Xvoid
  158. Xget_drives(char *buf)
  159. X{
  160. X    struct DirectoryEntry *de_head=NULL, *de;
  161. X
  162. X    buf[0]=0;
  163. X    AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  164. X    for(de=de_head; de; de=de->de_Next) {
  165. X        if( buf[0] )
  166. X            strcat( buf, "\240" );
  167. X        strcat( buf, de->de_Name );
  168. X    }
  169. X    FreeDAList(de_head);
  170. X}
  171. X
  172. Xstatic char infobuf[100];
  173. Xstatic char namebuf[12];
  174. X
  175. Xchar *
  176. Xdrive_name( char *name )
  177. X{
  178. X    struct DirectoryEntry *de_head=NULL, *de;
  179. X    struct MsgPort *proc=DeviceProc( name );
  180. X
  181. X    strcpy( namebuf, name );
  182. X    AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  183. X    for(de=de_head; de; de=de->de_Next)
  184. X        if( DeviceProc( de->de_Name) == proc ) 
  185. X            strcpy( namebuf, de->de_Name );
  186. X    FreeDAList(de_head);
  187. X
  188. X    return namebuf;
  189. X}
  190. X
  191. Xint
  192. Xdo_info( void )
  193. X{
  194. X    struct DirectoryEntry *de_head=NULL, *de;
  195. X    int i;
  196. X
  197. X    puts("Unit    Size  Bytes  Used Blk/Byt-Free Full Errs  Status    Name");
  198. X    Myprocess->pr_WindowPtr = (APTR)(-1);
  199. X
  200. X    if( ac==1 ) {
  201. X        AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  202. X        for(de=de_head; de; de=de->de_Next)
  203. X            oneinfo( de->de_Name, 0);
  204. X        FreeDAList(de_head);
  205. X    } else {
  206. X        for( i=1; i<ac; i++ )
  207. X            oneinfo( drive_name( av[i] ), 0 );
  208. X    }
  209. X
  210. X    Myprocess->pr_WindowPtr = (APTR) o_noreq;
  211. X    return 0;
  212. X}
  213. X
  214. Xchar *
  215. Xoneinfo( char *name, int mode )
  216. X{
  217. X    BPTR lock;
  218. X    struct InfoData *info;
  219. X    long size, free, freebl, blocks;
  220. X    char *p, buf[130], *state="          ";
  221. X    char *fmt="%s\240%s\240%d\240%d\240%d\240%s\240%d%%\240%d\240%s\240%s";
  222. X
  223. X    infobuf[0]=0;
  224. X    if( !name ) name="";
  225. X    strcpy(infobuf,"0");
  226. X    info=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
  227. X    if (lock=Lock(name,ACCESS_READ)) {
  228. X        if (Info(lock, info)) {
  229. X            PathName(lock, buf, 128L);
  230. X            if (p=index(buf,':')) *p = '\0';
  231. X            size  = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock);
  232. X            freebl= (info->id_NumBlocks-info->id_NumBlocksUsed);
  233. X            free  = freebl * info->id_BytesPerBlock;
  234. X            switch(info->id_DiskState) {
  235. X                case ID_WRITE_PROTECTED: state="Read Only "; break;
  236. X                case ID_VALIDATED:       state="Read/Write"; break;
  237. X                case ID_VALIDATING:      state="Validating"; break;
  238. X            }
  239. X            blocks=info->id_NumBlocks;
  240. X            if( mode==0 ) fmt="%-7s%5s%6d%7d%7d %5s%4d%%%4d  %s %s\n";
  241. X            sprintf(infobuf,fmt,
  242. X                name,
  243. X                itok( size ),
  244. X                info->id_BytesPerBlock,
  245. X                info->id_NumBlocksUsed,
  246. X                freebl,
  247. X                itok( free ),
  248. X                (blocks) ? (info->id_NumBlocksUsed * 100)/blocks : 0,
  249. X                info->id_NumSoftErrors,
  250. X                state,
  251. X                buf);
  252. X            if( mode==2 ) sprintf( infobuf, "%d", free );
  253. X            if( mode==3 ) sprintf( infobuf, "%d", freebl );
  254. X            if( mode==4 ) sprintf( infobuf, "%s", itok( free ));
  255. X            if( mode==5 ) sprintf( infobuf, "%s:", buf );
  256. X        } else
  257. X            pError (name);
  258. X        UnLock(lock);
  259. X    } else {
  260. X        if     ( mode==1 ) sprintf( infobuf, "%s\240No disk present", name );
  261. X        else if( mode==0 ) sprintf( infobuf, "%-7s No disk present\n",name);
  262. X        else if( mode==5 ) sprintf( infobuf, ""  );
  263. X        else               sprintf( infobuf, "0" );
  264. X    }
  265. X    if( mode==0 ) printf( "%s",infobuf);
  266. X    FreeMem(info,sizeof(struct InfoData));
  267. X    return infobuf;
  268. X}
  269. X
  270. X
  271. X/* things shared with display_file */
  272. X
  273. X#define DIR_SHORT 0x1
  274. X#define DIR_FILES 0x2
  275. X#define DIR_DIRS  0x4
  276. X#define DIR_NOCOL 0x8
  277. X#define DIR_NAMES 0x10
  278. X#define DIR_HIDE  0x20
  279. X#define DIR_LEN   0x40
  280. X#define DIR_TIME  0x80
  281. X#define DIR_BACK  0x100
  282. X#define DIR_UNIQ  0x200
  283. X#define DIR_IDENT 0x400
  284. X#define DIR_CLASS 0x800
  285. X#define DIR_QUIET 0x1000
  286. X#define DIR_AGE   0x2000
  287. X#define DIR_VIEW  0x4000
  288. X#define DIR_NOTE  0x8000
  289. X
  290. Xstatic BPTR lastlock;
  291. Xstatic int filecount, col, wwidth;
  292. Xstatic long bytes, blocks;
  293. X
  294. X/* the args passed to do_dir will never be expanded */
  295. X
  296. Xextern expand_err;
  297. Xextern int w_width;
  298. X
  299. X
  300. Xstatic struct DateStamp Stamp;
  301. X
  302. Xint
  303. Xdo_dir( void )
  304. X{
  305. X    int i=1, c, eac, reverse, nump=ac, retcode=0;
  306. X    char **eav, **av1, **av2, inter=interactive();
  307. X    int (*func)(), ac1, ac2;
  308. X
  309. X    if( options&DIR_CLASS ) options|=DIR_IDENT;
  310. X    if( ac == i) ++nump, av[i]="";
  311. X    if( !(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
  312. X    if( options&DIR_UNIQ) {
  313. X        if( ac-i!=2 )  { show_usage(NULL); return 20; }
  314. X        i=0, nump=3;
  315. X    }
  316. X
  317. X    if( options&DIR_AGE )
  318. X        DateStamp( &Stamp );
  319. X
  320. X    col = filecount = bytes = blocks = 0L;
  321. X    lastlock=NULL;
  322. X
  323. X    wwidth=77;
  324. X    if( inter ) printf( "\033[?7l" ), wwidth=w_width; /* end of line wrap off */
  325. X
  326. X    prepscroll(0);
  327. X    for( ; i<nump && !CHECKBREAK(); ++i ) {
  328. X        if( options&DIR_UNIQ ) {
  329. X            switch( i ) {
  330. X                case 0: av1=expand( av[ac-2], &ac1 );
  331. X                        av2=expand( av[ac-1], &ac2 );
  332. X                        eav=without( av1, ac1, av2, ac2, &eac, 1 );
  333. X                        break;
  334. X                case 1: printf("\nCommon files\n");
  335. X                        eav=and( av1, ac1, av2, ac2, &eac, 1 );
  336. X                        break;
  337. X                case 2: printf("\n");
  338. X                        eav=without( av2, ac2, av1, ac1, &eac, 1 );
  339. X                        break;
  340. X            }
  341. X            col = filecount = bytes = blocks = 0L;
  342. X            lastlock=NULL;
  343. X        } else if (!(eav = expand(av[i], &eac)) && expand_err) {
  344. X            pError(av[i]);
  345. X            retcode=5;
  346. X            continue;
  347. X        }
  348. X
  349. X        reverse= ( options&DIR_BACK ) ? 1 : 0;
  350. X        func=cmp;
  351. X        if( options & DIR_TIME) func=datecmp;
  352. X        if( options & DIR_LEN ) func=sizecmp;
  353. X        if( options & DIR_CLASS)func=classcmp;
  354. X        DirQuickSort(eav, eac, func, reverse);
  355. X        for(c=0; c<eac && !CHECKBREAK(); ++c) {
  356. X            if( options & DIR_HIDE ) {
  357. X                char *b=BaseName(eav[c]);
  358. X                int  l=strlen(b)-5;
  359. X                struct file_info *info =
  360. X                    (struct file_info *)(eav[c]-sizeof(struct file_info));
  361. X                if(*b=='.'|| (l>=0 && !strcmp(b+l,".info"))||(info->flags&128))
  362. X                    continue;
  363. X            }
  364. X            if (options & DIR_NAMES)
  365. X                puts(eav[c]);
  366. X            else
  367. X                display_file(eav[c]);
  368. X        }
  369. X
  370. X        if (col) { quickscroll(); printf("\n"); col=0; }
  371. X        if (options&DIR_UNIQ || (filecount>1 && i==nump-1)) {
  372. X            blocks += filecount; /* account for dir blocks */
  373. X            quickscroll();
  374. X            printf(" %ld Blocks, %s Bytes used in %d files\n",
  375. X                blocks, itoa(bytes), filecount);
  376. X        }
  377. X        if( options&DIR_UNIQ )
  378. X            free(eav);
  379. X        else 
  380. X            free_expand (eav);
  381. X        if (lastlock) UnLock(lastlock), lastlock=0;
  382. X    }
  383. X    if (lastlock) UnLock(lastlock), lastlock=0;
  384. X
  385. X    if( options&DIR_UNIQ )
  386. X        free_expand( av1 ), free_expand( av2 );
  387. X
  388. X    if( inter ) printf( "\033[?7h" );                /* end of line wrap off */
  389. X
  390. X    return retcode;
  391. X}
  392. X
  393. X
  394. Xstatic void
  395. Xdisplay_file( char *filestr )
  396. X{
  397. X    int isadir,slen;
  398. X    char sc, *base, buf[130];
  399. X    struct file_info *info;
  400. X    BPTR thislock;
  401. X
  402. X    base=BaseName(filestr);
  403. X    sc = *base;
  404. X    *base = '\0';
  405. X    thislock=Lock(filestr,SHARED_LOCK);
  406. X    /* if (thislock==NULL) return; */
  407. X    if (lastlock==NULL || CompareLock(thislock,lastlock)) {
  408. X        /* struct InfoData *id=AllocMem( sizeof(struct InfoData), 0); */
  409. X        if (col) { quickscroll(); printf("\n"); col=0; }
  410. X        quickscroll();
  411. X        PathName(thislock, buf, 128L);
  412. X        /* Info( thislock, id ); */
  413. X        printf("Directory of %s\n", buf );
  414. X        /*itok((id->id_NumBlocks-id->id_NumBlocksUsed)*id->id_BytesPerBlock));*/
  415. X        /* FreeMem( id, sizeof(struct InfoData)); */
  416. X        if (lastlock) UnLock(lastlock);
  417. X        lastlock=thislock;
  418. X    } else
  419. X        UnLock(thislock);
  420. X
  421. X    *base    = sc;
  422. X    if((slen = strlen(base)+1) & 1 ) ++slen;
  423. X    info     = (struct file_info *)(filestr - sizeof(struct file_info));
  424. X    isadir   = info->size<0;
  425. X
  426. X    if (!(((options & DIR_FILES) && !isadir) ||
  427. X                     ((options & DIR_DIRS) &&  isadir)))
  428. X        return;
  429. X    if (isadir && !(options & DIR_NOCOL)) printf (o_hilite);
  430. X    if (options & DIR_SHORT) {
  431. X        slen= (slen>18) ? 37 : 18;
  432. X        if (col && col+slen>=wwidth )
  433. X            { quickscroll(); printf("\n"); col = 0; }
  434. X        printf(" %-*s",slen,base);
  435. X        col+= ++slen;
  436. X    } else {
  437. X        quickscroll();
  438. X        printf("   %-24s %s \n",base,formatfile(info));
  439. X    }
  440. X    if (isadir && !(options & DIR_NOCOL))
  441. X        printf(o_lolite);
  442. X    if(info->size>0)
  443. X        bytes  += info->size;
  444. X    blocks += info->blocks;
  445. X    filecount++;
  446. X}
  447. X
  448. X/* will have either of these formats:
  449. X *
  450. X *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  451. X *    fullfilename'\0'hsparwed NNNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  452. X *                              1111111111222222222233333333334 4  4
  453. X *                    01234567890123456789012345678901234567890 1  2
  454. X */
  455. X
  456. Xstatic char linebuf[140];
  457. Xstatic long dlen, dblocks;
  458. X
  459. Xstatic void
  460. Xcount( FIB *fib )
  461. X{
  462. X    dlen+=fib->fib_Size;
  463. X    dblocks+=fib->fib_NumBlocks+1;
  464. X}
  465. X
  466. Xchar *
  467. Xformatfile( struct file_info *info)
  468. X{
  469. X    char *str=linebuf, *class, *t;
  470. X    int i, stat;
  471. X
  472. X    if( options & DIR_NOTE ) {
  473. X        struct DPTR *dp;
  474. X        if( dp=dopen( (char *)(info+1), &stat )) {
  475. X            strcpy( str, dp->fib->fib_Comment );
  476. X            dclose( dp );
  477. X        }
  478. X        return linebuf;
  479. X    }
  480. X
  481. X    *str++= info->flags & 1<<30 ? 'c' : '-';
  482. X    for (i=7; i>=0; i--)
  483. X        *str++ = ((info->flags & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
  484. X    if (info->size >= 0)
  485. X        sprintf(str,options&DIR_QUIET?" %7ld ":" %7ld %4ld  ",
  486. X                    info->size, info->blocks);
  487. X    else
  488. X        strcpy(str,options&DIR_QUIET?"   <Dir> ":"   <Dir>       ");
  489. X    str+=strlen(str);
  490. X    if( options&DIR_VIEW && info->size<0 ) {
  491. X        dlen=dblocks=0;
  492. X        recurse2( (char *)(info+1),count);
  493. X        sprintf( str, "%10s",itoa(dlen));
  494. X        info->size=dlen; info->blocks=dblocks;
  495. X    } else if( options&DIR_IDENT ) {
  496. X        if( *info->class!=1 )
  497. X            strcpy(str,info->class);
  498. X        else if( class=getclass((char *)(info+1)))
  499. X            if( t=index(strncpy(str,class,40),0xA0) )
  500. X                *t=0;
  501. X    } else if( options&DIR_AGE) {
  502. X        long mins=0;
  503. X        if( Stamp.ds_Days!=0 ) {
  504. X            mins =Stamp.ds_Days*1440 + Stamp.ds_Minute;
  505. X            mins-=info->date.ds_Days*1440 + info->date.ds_Minute;
  506. X        }
  507. X        if( mins>=0 )
  508. X            sprintf(str,"%4d %02d:%02d",mins/1440,mins/60%60,mins%40);
  509. X        else 
  510. X            sprintf(str,"Future");
  511. X    } else if( !(options&DIR_VIEW) )
  512. X        strcat(str,dates(&info->date));
  513. X    return linebuf;
  514. X}
  515. X
  516. X
  517. Xint
  518. Xdo_quit( void )
  519. X{
  520. X    if (Src_stack) {
  521. X        Quit = 1;
  522. X        return(do_return());
  523. X    }
  524. X    main_exit(0);
  525. X    return 0;
  526. X}
  527. X
  528. Xint
  529. Xdo_echo( void )
  530. X{
  531. X    char *args=compile_av(av,1,ac,' ',0);
  532. X    fprintf( (options&2)?stderr:stdout, (options&1)?"%s":"%s\n",args );
  533. X    free(args);
  534. X    return 0;
  535. X}
  536. X
  537. X
  538. Xstatic int
  539. Xbreakcheckd(void)
  540. X{
  541. X    int ret=!o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_D;
  542. X    SetSignal(0L, SIGBREAKF_CTRL_D);
  543. X    if( ret )
  544. X        fprintf(stderr,"^D\n");
  545. X    return ret;
  546. X}
  547. X
  548. X/* gets a line from file, joining two lines if the first ends in '\' */
  549. X
  550. Xstatic char *
  551. Xmyfgets(char *buf, int buflen, FILE *file)
  552. X{
  553. X    char *bufptr=buf, *limit=buf+buflen;
  554. X
  555. X    do {
  556. X        if (fgets(bufptr, limit-bufptr, file)==NULL) {
  557. X            if (bufptr != buf)
  558. X                fprintf(stderr,"Source: file ends in '\\'\n");
  559. X            return NULL;
  560. X        }
  561. X        bufptr = bufptr+strlen(bufptr)-2;
  562. X    } while (*bufptr=='\\');
  563. X    return buf;
  564. X}
  565. X
  566. Xint
  567. Xdo_source( char *str )
  568. X{
  569. X    FILE *fi;
  570. X    char *buf;
  571. X    int len;
  572. X
  573. X    if (Src_stack == MAXSRC) {
  574. X        ierror(NULL,217);
  575. X        return -1;
  576. X    }
  577. X    if ((fi = fopen (av[1], "r")) == 0)
  578. X        { pError(av[1]); return -1;    }
  579. X    buf=malloc(512);
  580. X    set_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  581. X    ++H_stack;
  582. X    Src_pos[Src_stack] = 0;
  583. X    Src_base[Src_stack] = fi;
  584. X    Src_if[Src_stack]=If_stack;
  585. X    ++Src_stack;
  586. X    while (myfgets (buf, 512, fi) && !dobreak() && !breakcheckd()) {
  587. X        len = strlen(buf);
  588. X        if(buf[len-1]=='\n')
  589. X            buf[len-1] = '\0';
  590. X        Src_pos[Src_stack - 1] += len;
  591. X        if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
  592. X        exec_command (buf);
  593. X    }
  594. X    --H_stack;
  595. X    --Src_stack;
  596. X    if( If_stack>Src_if[Src_stack] )
  597. X        If_stack=Src_if[Src_stack], disable=If_stack && If_base[If_stack-1];
  598. X
  599. X    if (forward_goto) ierror(NULL,501);
  600. X    forward_goto = 0;
  601. X    unset_level(LEVEL_SOURCE + Src_stack);
  602. X    unset_var(LEVEL_SET, v_gotofwd);
  603. X    unset_var(LEVEL_SET, v_passed);
  604. X    free(buf);
  605. X    fclose (fi);
  606. X    return 0;
  607. X}
  608. X
  609. X/* set process cwd name and $_cwd, if str != NULL also print it. */
  610. X
  611. Xint
  612. Xdo_pwd( char *str )
  613. X{
  614. X    char pwd[130];
  615. X
  616. X    PathName(Myprocess->pr_CurrentDir, pwd, 128L);
  617. X    if (str) puts(pwd);
  618. X    set_var(LEVEL_SET, v_cwd, pwd);
  619. X    /* put the current dir name in our CLI task structure */
  620. X    CtoBStr(pwd, Mycli->cli_SetName, 128L);
  621. X    return 0;
  622. X}
  623. X
  624. X/*
  625. X * CD
  626. X *
  627. X * CD(str, 0)      -do CD operation.
  628. X *
  629. X */
  630. X
  631. Xextern int qcd_flag;
  632. X
  633. Xstatic char lastqcd[80];
  634. Xstatic lastoffs;
  635. X
  636. Xint
  637. Xdo_cd( char *str )
  638. X{
  639. X    BPTR oldlock, filelock;
  640. X    FILE *file;
  641. X    char buf[100], *old;
  642. X    int  i=1, repeat;
  643. X
  644. X    if( options & 1 ) {
  645. X        if( !(file=fopen( o_csh_qcd, "w" )))
  646. X            { fprintf(stderr,"Can't open output\n"); return 20; }
  647. X        for( ; i<ac && !breakcheck(); i++ ) {
  648. X            fprintf(file,"%s\n",av[i]);
  649. X            strcpy(buf,av[i]);
  650. X            appendslash( buf );
  651. X            expand_all( buf, file );
  652. X        }
  653. X        fclose(file);
  654. X        return 0;
  655. X    }
  656. X
  657. X    str= ( has_wild && ac>=2 ) ? av[1] : next_word(str);
  658. X    if (!strcmp("..",str)) str="/";
  659. X
  660. X    if( !*str ) {
  661. X        printf("%s\n", get_var( LEVEL_SET, v_cwd ));
  662. X        return 0;
  663. X    }
  664. X
  665. X    if (filelock=Lock(str,ACCESS_READ)) {
  666. X        lastqcd[0]=0;
  667. X        if (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
  668. X    } else {
  669. X        repeat= !strncmp( lastqcd, str, 79 );
  670. X        strncpy( lastqcd, str, 79);
  671. X
  672. X        if( !quick_cd( buf, av[i], repeat) )
  673. X            { fprintf(stderr,"Object not found %s\n",str); return 20; }
  674. X        if (!(filelock=Lock(buf,ACCESS_READ))) 
  675. X            { pError(buf); return 20; }
  676. X    }
  677. X    if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  678. X    if( !(old=get_var(LEVEL_SET, v_cwd)) )
  679. X        old="";
  680. X    set_var(LEVEL_SET, v_lcd, old);
  681. X    do_pwd(NULL);
  682. X
  683. X    return 0;
  684. X}
  685. X
  686. Xchar *
  687. Xquick_cd( char *buf, char *name, int repeat )
  688. X{
  689. X    qcd_flag=repeat ? 2 : 1;
  690. X    strcpy(buf,name);
  691. X    if( quicksearch( o_csh_qcd, 1, buf)!=2 )
  692. X        return NULL;
  693. X    return buf;
  694. X}
  695. X
  696. X
  697. Xint
  698. Xdo_mkdir( void )
  699. X{
  700. X    int i;
  701. X    BPTR lock;
  702. X    
  703. X    for (i=1; i<ac; ++i) {
  704. X        if (exists(av[i]))
  705. X            ierror(av[i],203);
  706. X        else if (lock=CreateDir(av[i]))
  707. X            UnLock (lock);
  708. X        else
  709. X            pError(av[i]);
  710. X    }
  711. X    return 0;
  712. X}
  713. X
  714. Xint
  715. Xdo_mv( void )
  716. X{
  717. X    char *dest, buf[256];
  718. X    int dirflag, i;
  719. X
  720. X    dirflag=isdir(dest=av[--ac]);
  721. X    if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  722. X    for (i=1; i<ac; ++i) {
  723. X        strcpy(buf, dest);
  724. X        if (dirflag) TackOn(buf, BaseName(av[i]));
  725. X        if (Rename(av[i], buf)==0)
  726. X            { pError(av[i]); return -1; }
  727. X        else 
  728. X            clear_archive_bit( buf );
  729. X    }
  730. X    return 0;
  731. X}
  732. X
  733. Xstatic int dirstoo;
  734. X
  735. Xint
  736. Xall_args( int (*action)(char *str), int dirsflag )
  737. X{
  738. X    int i;
  739. X
  740. X    dirstoo=dirsflag;
  741. X    for ( i=1; i<ac && !dobreak(); ++i)
  742. X        if (isdir(av[i])) {
  743. X            if (options & 1) recurse(av[i], action);
  744. X            else if (dirstoo) (*action)(av[i]);
  745. X        } else
  746. X            (*action)(av[i]);
  747. X    return 0;
  748. X}
  749. X
  750. Xchar *searchstring;
  751. Xchar docr;
  752. X
  753. X#define SEARCH_REC   1
  754. X#define SEARCH_CASE  2
  755. X#define SEARCH_WILD  4
  756. X#define SEARCH_NUM   8
  757. X#define SEARCH_EXCL  16
  758. X#define SEARCH_QUIET 32
  759. X#define SEARCH_VERB  64
  760. X#define SEARCH_BIN   128
  761. X#define SEARCH_FILE  256
  762. X#define SEARCH_ABORT 512
  763. X#define SEARCH_LEFT  1024
  764. X#define SEARCH_ONLY  2048
  765. X
  766. Xstatic int abort_search;
  767. Xstatic char lowbuf[256], file_name, file_cr;
  768. X
  769. Xstatic int
  770. Xsearch_file( char *s )
  771. X{
  772. X    FILE *fopen(), *fi;
  773. X    char *p, *q;
  774. X    int nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
  775. X    char buf[256], searchit[120], first, left;
  776. X
  777. X    if( abort_search )
  778. X        return 0;
  779. X
  780. X    nocasedep=!(options & SEARCH_CASE);
  781. X    lctr= docr= file_name= file_cr= 0;
  782. X    if (!(options & (SEARCH_QUIET|SEARCH_FILE)))
  783. X        if( options & SEARCH_VERB )
  784. X            printf("Examining %s...\n",s);
  785. X        else 
  786. X            printf("\015Examining %s...                  ",s), docr=1;
  787. X
  788. X    strcpy(searchit,searchstring);
  789. X    if (options & SEARCH_WILD) strcat(searchit,"\n");
  790. X    len=strlen(searchit);
  791. X    if (nocasedep) strupr(searchit);
  792. X    first=*searchit;
  793. X
  794. X    if( strcmp("STDIN",s) && !(options&SEARCH_WILD) && !excl ||
  795. X                 options&SEARCH_BIN )
  796. X        if( quicksearch(s,nocasedep,searchit) )
  797. X            return 0;
  798. X
  799. X    if( options&SEARCH_BIN )
  800. X        { fprintf(stderr,"Out of memory\n"); return 20; }
  801. X
  802. X    fi = strcmp("STDIN",s) ?  fopen(s,"r") : stdin;
  803. X    if (fi==NULL) { pError(s); return 20; }
  804. X
  805. X    prepscroll(0);
  806. X
  807. X    while (fgets(buf,256,fi) && !dobreak()) {
  808. X        lctr++; left=1;
  809. X        if (options & SEARCH_WILD)
  810. X            yesno=compare_ok(searchit, buf, options&SEARCH_CASE);
  811. X        else {
  812. X            if (nocasedep) {
  813. X                strcpy(lowbuf,buf);
  814. X                strupr(lowbuf);
  815. X                p=lowbuf;
  816. X            } else
  817. X                p=buf;
  818. X            q=p;
  819. X            while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
  820. X            yesno= (p!=NULL);
  821. X            left = --p - q;
  822. X        }
  823. X        if( yesno ^ excl )
  824. X            if(!(options&SEARCH_ONLY)|| !isalphanum(p[-1])&&!isalphanum(p[len]))
  825. X                if( found(buf, lctr, 0, s, left ) )
  826. X                    break;
  827. X    }
  828. X    if (fi!=stdin) fclose (fi);
  829. X    if( file_cr ) printf("\n");
  830. X    return 0;
  831. X}
  832. X
  833. Xint qcd_flag, qcd_offs;
  834. X
  835. Xstatic int
  836. Xquicksearch( char *name, int nocasedep, char *pattern )
  837. X{
  838. X    int i, ptrn=strlen(pattern);
  839. X    char ut[256], *buffer, *lend;
  840. X    char *uptab=ut, *get, c, *lpos, *lstart;
  841. X    int len, lnum, qcd=qcd_flag, repeat=(qcd==2 && qcd_offs!=0);
  842. X    int sofar, got;
  843. X    BPTR fh;
  844. X
  845. X#ifdef AZTEC_C
  846. X    while(0) while(0) c=c=0, uptab=uptab=ut, get=get=NULL;
  847. X#endif
  848. X
  849. X    qcd_flag=0;
  850. X    if( !(fh=Open(name,MODE_OLDFILE))) { 
  851. X        i=(long)IoErr(), docr=0;
  852. X        printf("\n");
  853. X        ierror(name,i);
  854. X        return 1;
  855. X    }
  856. X    len=filesize( name );
  857. X    if( !(buffer=(void *)malloc(len+2))) { Close(fh); return 0; }
  858. X    sofar=0;
  859. X    do {
  860. X        got=Read( fh, (char *)buffer+sofar, 60000);
  861. X        sofar+=got;
  862. X    } while( got==60000 );
  863. X    Close( fh);
  864. X    if( sofar != len ) { pError(pattern); return 1; }
  865. X
  866. X    if( nocasedep )
  867. X        strupr( pattern );
  868. X
  869. X    if( !qcd )
  870. X        prepscroll(0);
  871. X
  872. X    for( i=0; i<256; i++ ) uptab[i]=i;
  873. X    if( nocasedep ) for( i='a'; i<='z'; i++ ) uptab[i]=i-'a'+'A';
  874. Xretry:
  875. X    c=*pattern, buffer[len]=c, buffer[len+1]=c;
  876. X    get= (qcd==2) ? buffer+qcd_offs : buffer;
  877. X    if( qcd==1 ) qcd_offs=0;
  878. X
  879. X    lpos=lstart=buffer, lnum=1;
  880. X    for( ;; ) {
  881. X        do ; while( uptab[*get++]!=c );
  882. X        if( --get>=buffer + len )
  883. X            break;
  884. X        for( i=1; i<ptrn; i++ )
  885. X            if( uptab[get[i]]!=pattern[i] )
  886. X                break;
  887. X        if( i==ptrn ) {
  888. X            for( ;lpos<get; lpos++ )
  889. X                if( *lpos=='\n' )
  890. X                    lstart=lpos+1, lnum++;
  891. X            for( lend=lstart+1; *lend!='\n'; lend++ ) ;
  892. X            if( qcd ) {
  893. X                if( get[-1]==':' || get[-1]=='/' ||
  894. X                      lpos==lstart && lend[-1]==':' ) {
  895. X                    char *tmp;
  896. X                    for( tmp=get+ptrn; *tmp&& *tmp!='\n'&& *tmp!='/'; tmp++ );
  897. X                    if( *tmp!='/' ) {
  898. X                        *lend=0;
  899. X                        strncpy(pattern,lstart,79);
  900. X                        qcd_offs=lend-buffer;
  901. X                        free( buffer );
  902. X                        return 2;
  903. X                    }
  904. X                } else 
  905. X                    lend=lpos+1;
  906. X            } else {
  907. X                *lend=0;
  908. X                if(!(options&SEARCH_ONLY) ||
  909. X                     !isalphanum(lpos[-1])&&!isalphanum(lpos[ptrn]))
  910. X                    if(found(lstart, lnum, get-buffer, name, lpos==lstart ))
  911. X                        break;
  912. X                *lend='\n';
  913. X            }
  914. X            get=lend+1;
  915. X        } else
  916. X            get++;
  917. X    }
  918. X    if( repeat )  { repeat=0; qcd_offs=0; goto retry; }
  919. X    if( file_cr ) { printf("\n"); quickscroll(); }
  920. X    free( buffer );
  921. X    return 1;
  922. X}
  923. X
  924. Xstatic int
  925. Xfound( char *lstart, int lnum, int loffs, char *name, char left )
  926. X{
  927. X    int fileabort=0;
  928. X
  929. X    if ( docr )
  930. X        { quickscroll(); printf("\n"); docr=0; }
  931. X
  932. X    if( (options&SEARCH_LEFT) && !left)
  933. X        return 0;
  934. X
  935. X    if( options&SEARCH_FILE ) {
  936. X        file_cr=1;
  937. X        if( !file_name )
  938. X            printf("%s",name), file_name=1;
  939. X        if( options&SEARCH_NUM )
  940. X            fileabort=1;
  941. X        else 
  942. X            printf(" %d",lnum);
  943. X    } else if( options & SEARCH_BIN ) {
  944. X        if (!(options & SEARCH_NUM))
  945. X            printf("Byte offset %d\n",loffs);
  946. X        else 
  947. X            printf("%d\n",loffs);
  948. X        quickscroll();
  949. X    } else {
  950. X        if (!(options & SEARCH_NUM))
  951. X            printf("%4d ",lnum);
  952. X        printf((lstart[strlen(lstart)-1]=='\n')?"%s":"%s\n",lstart);
  953. X        quickscroll();
  954. X    }
  955. X    abort_search= options&SEARCH_ABORT;
  956. X    return dobreak() || fileabort || abort_search;
  957. X}
  958. X
  959. X
  960. Xint
  961. Xdo_search( void )
  962. X{
  963. X    if( Cout_name ) options |= SEARCH_VERB;
  964. X    abort_search=0;
  965. X    searchstring=av[--ac];
  966. X    all_args(search_file, 0);
  967. X    if(docr) printf("\n"),docr=0;
  968. X    return 0;
  969. X}
  970. X
  971. Xstatic int
  972. Xrm_file(char *file)
  973. X{
  974. X    if ( file[strlen(file)-1]=='/' ) file[strlen(file)-1]=0;
  975. X    if (has_wild) printf(" %s...",file);
  976. X    if (options & 2) SetProtection(file,0L);
  977. X    if (!DeleteFile(file)) 
  978. X        { pError (file); return 20; }
  979. X    else if (has_wild)
  980. X        printf("Deleted\n");
  981. X    return 0;
  982. X}
  983. X
  984. Xint
  985. Xdo_rm( void )
  986. X{
  987. X    all_args( rm_file, 1);
  988. X    return 0;
  989. X}
  990. X
  991. Xstatic void
  992. Xrecurse(char *name, int (*action)(char *))
  993. X{
  994. X    BPTR lock, cwd;
  995. X    FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  996. X    char *namecopy=malloc(256);
  997. X
  998. X    if (name[0] =='\0') return;
  999. X    namecopy[0]=0;
  1000. X    if (lock=Lock(name,ACCESS_READ)) {
  1001. X        cwd =CurrentDir(lock);
  1002. X        if (Examine(lock, fib))
  1003. X            while (ExNext(lock, fib) && !CHECKBREAK()) {
  1004. X                if (*namecopy)
  1005. X                    { (*action)(namecopy); namecopy[0]=0; }
  1006. X                if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
  1007. X                else strcpy(namecopy,fib->fib_FileName);
  1008. X            }
  1009. X        if (*namecopy) (*action)(namecopy);
  1010. X        UnLock(CurrentDir(cwd));
  1011. X        if (dirstoo) (*action)(name);
  1012. X    } else
  1013. X        pError(name);
  1014. X    free(namecopy);
  1015. X    FreeMem(fib, (long)sizeof(FIB));
  1016. X}
  1017. X
  1018. Xstatic void
  1019. Xrecurse2( char *name, void (*action)(FIB *))
  1020. X{
  1021. X    BPTR lock, cwd;
  1022. X    FIB  *fib=(FIB *)AllocMem(sizeof(FIB),MEMF_PUBLIC);
  1023. X
  1024. X    if (lock=Lock(name,ACCESS_READ)) {
  1025. X        cwd =CurrentDir(lock);
  1026. X        if (Examine(lock, fib))
  1027. X            while (ExNext(lock, fib) && !CHECKBREAK()) {
  1028. X                (*action)(fib);
  1029. X                if (fib->fib_DirEntryType>=0)
  1030. X                    recurse2(fib->fib_FileName,action);
  1031. X            }
  1032. X        UnLock(CurrentDir(cwd));
  1033. X    }
  1034. X
  1035. X    FreeMem(fib, sizeof(FIB));
  1036. X}
  1037. X
  1038. X
  1039. Xint
  1040. Xdo_history( void )
  1041. X{
  1042. X    struct HIST *hist;
  1043. X    int i = H_tail_base;
  1044. X    int len = (av[1]) ? strlen(av[1]) : 0;
  1045. X
  1046. X    for (hist = H_tail; hist && !dobreak(); hist = hist->prev, i++)
  1047. X        if (len == 0 || !strncmp(av[1], hist->line, len))
  1048. X            printf("%3d %s\n", i, hist->line);
  1049. X    return 0;
  1050. X}
  1051. X
  1052. Xint
  1053. Xdo_mem( void )
  1054. X{
  1055. X    static long clast, flast;
  1056. X    long cfree, ffree;
  1057. X    char *desc="Free";
  1058. X
  1059. X    Forbid();
  1060. X    cfree = AvailMem (MEMF_CHIP);
  1061. X    ffree = AvailMem (MEMF_FAST);
  1062. X    Permit();
  1063. X    if( options&8 ) {
  1064. X        clast=cfree, flast=ffree;
  1065. X        return 0;
  1066. X    }
  1067. X    if( options&16 )
  1068. X        cfree=clast-cfree, ffree=flast-ffree, desc="Used";
  1069. X    if( options&4 ) {
  1070. X        if     ( options & 1 ) printf("%ld\n",cfree);
  1071. X        else if( options & 2 ) printf("%ld\n",ffree);
  1072. X        else                   printf("%ld\n",cfree+ffree);
  1073. X    } else {
  1074. X        if     ( options & 1 ) printf("Free CHIP memory %s\n",itoa(cfree));
  1075. X        else if( options & 2 ) printf("Free FAST memory %s\n",itoa(ffree));
  1076. X        else {
  1077. X            if(ffree) {
  1078. X                printf("FAST memory: %s\n",itoa(ffree));
  1079. X                printf("CHIP memory: %s\n",itoa(cfree));
  1080. X            }
  1081. X            printf("Total  %s: %s\n",desc,itoa(cfree+ffree));
  1082. X        }
  1083. X    }
  1084. X    return 0;
  1085. X}
  1086. X
  1087. Xint
  1088. Xdo_forline( void )
  1089. X{
  1090. X    char vname[33], buf[256], *cstr;
  1091. X    int lctr;
  1092. X    FILE *f;
  1093. X
  1094. X    strcpy(vname,av[1]);
  1095. X    f=fopen(av[2],"r");
  1096. X    if (f==NULL) pError(av[2]);
  1097. X    lctr=0;
  1098. X    ++H_stack;
  1099. X    cstr = compile_av (av, 3, ac, ' ', 0);
  1100. X    while (fgets(buf,256,f) && !dobreak()) {
  1101. X        buf[strlen(buf)-1]='\0';    /* remove CR */
  1102. X        lctr++;
  1103. X        set_var(LEVEL_SET, vname, buf);
  1104. X        sprintf(buf,"%d",lctr);
  1105. X        set_var(LEVEL_SET, v_linenum, buf);
  1106. X        exec_command(cstr);
  1107. X    }
  1108. X    fclose(f);
  1109. X    --H_stack;
  1110. X    free (cstr);
  1111. X    unset_var (LEVEL_SET, vname);
  1112. X    unset_var (LEVEL_SET, v_linenum);
  1113. X    return 0;
  1114. X}
  1115. X
  1116. Xint
  1117. Xdo_fornum( void )
  1118. X{
  1119. X    char vname[33], buf[16];
  1120. X    int n1, n2, step, i=1, verbose;
  1121. X    char *cstr;
  1122. X
  1123. X    verbose=(options & 1);
  1124. X    strcpy(vname,av[i++]);
  1125. X    n1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1126. X    n2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1127. X    if (options & 2) {
  1128. X        step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1129. X    } else
  1130. X        step=1;
  1131. X    ++H_stack;
  1132. X    cstr = compile_av (av, i, ac, ' ', 0);
  1133. X    for (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) {
  1134. X        if (verbose) fprintf(stderr, "fornum: %d\n", i);
  1135. X        sprintf(buf,"%d",i);
  1136. X        set_var (LEVEL_SET, vname, buf);
  1137. X        exec_command(cstr);
  1138. X    }
  1139. X    --H_stack;
  1140. X    free (cstr);
  1141. X    unset_var (LEVEL_SET, vname);
  1142. X    return 0;
  1143. X}
  1144. X
  1145. X/*
  1146. X * foreach var_name  ( str str str str... str ) commands
  1147. X * spacing is important (unfortunately)
  1148. X *
  1149. X * ac=0    1 2 3 4 5 6 7
  1150. X * foreach i ( a b c ) echo $i
  1151. X * foreach i ( *.c ) "echo -n "file ->";echo $i"
  1152. X */
  1153. X
  1154. Xint
  1155. Xdo_foreach( void )
  1156. X{
  1157. X    int cstart, cend;
  1158. X    char *cstr, **fav, vname[33];
  1159. X    int i=1, verbose;
  1160. X
  1161. X    verbose=(options & 1);
  1162. X    strcpy(vname, av[i++]);
  1163. X    if (*av[i] == '(') i++;
  1164. X    cstart = i;
  1165. X    while (i<ac && *av[i] != ')') i++;
  1166. X    if (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  1167. X    ++H_stack;
  1168. X    cend = i;
  1169. X
  1170. X    fav = (char **)malloc(sizeof(char *) * (ac));
  1171. X    cstr = compile_av (av, cend + 1, ac, ' ', 0);
  1172. X
  1173. X    for (i = cstart; i < cend; ++i) fav[i] = av[i];
  1174. X
  1175. X    for (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  1176. X        set_var (LEVEL_SET, vname, fav[i]);
  1177. X        if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
  1178. X        exec_command(cstr);
  1179. X    }
  1180. X    --H_stack;
  1181. X    free (fav);
  1182. X    free (cstr);
  1183. X    unset_var (LEVEL_SET, vname);
  1184. X    return 0;
  1185. X}
  1186. X
  1187. Xint
  1188. Xdo_forever( char *str )
  1189. X{
  1190. X    int rcode = 0;
  1191. X    char *ptr = next_word( str );
  1192. X
  1193. X    ++H_stack;
  1194. X    for (;;) {
  1195. X        if (CHECKBREAK()) { rcode = 20; break; }
  1196. X        if (exec_command (ptr) < 0) {
  1197. X            str = get_var(LEVEL_SET, v_lasterr);
  1198. X            rcode = (str) ? atoi(str) : 20;
  1199. X            break;
  1200. X        }
  1201. X    }
  1202. X    --H_stack;
  1203. X    return rcode;
  1204. X}
  1205. X
  1206. Xextern struct IntuitionBase *IntuitionBase;
  1207. X
  1208. Xint
  1209. Xdo_window( void )
  1210. X{
  1211. X    long x=-1, y=-1, w=-1, h=-1, maxwidth, maxheight, arg[5];
  1212. X    int i;
  1213. X
  1214. X    if(options & 32) {
  1215. X        struct Screen *scrn;
  1216. X        struct Window *window;
  1217. X        char buf[80];
  1218. X        buf[40]=0;
  1219. X        for (scrn=IntuitionBase->FirstScreen; scrn; scrn=scrn->NextScreen) {
  1220. X            buf[0]=0;
  1221. X            if( scrn->Title )
  1222. X                strncpy(buf,scrn->Title,40);
  1223. X            printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  1224. X                buf,
  1225. X                scrn->LeftEdge,
  1226. X                scrn->TopEdge,
  1227. X                scrn->Width,
  1228. X                scrn->Height
  1229. X            );
  1230. X            for (window=scrn->FirstWindow; window; window=window->NextWindow) {
  1231. X                buf[0]=0;
  1232. X                if( window->Title )
  1233. X                    strncpy(buf,window->Title,40);
  1234. X                printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  1235. X                    buf,
  1236. X                    window->LeftEdge,
  1237. X                    window->TopEdge,
  1238. X                    window->Width,
  1239. X                    window->Height
  1240. X                );
  1241. X            }
  1242. X        }
  1243. X        return 0;
  1244. X    }
  1245. X
  1246. X    if( o_nowindow || !Win )
  1247. X        return 20;
  1248. X
  1249. X    maxwidth = Win->WScreen->Width;
  1250. X    maxheight= Win->WScreen->Height;
  1251. X    if( options&1 )
  1252. X        x=Win->LeftEdge,y=Win->TopEdge,w=Win->MinWidth,h=Win->MinHeight;
  1253. X    if( options&2 ) x=y=0, w=maxwidth, h=maxheight;
  1254. X    if( options&4 ) WindowToFront(Win);
  1255. X    if( options&8 ) WindowToBack(Win);
  1256. X    if( options&16) ActivateWindow(Win);
  1257. X    if( ac >= 5) {
  1258. X        for(i=1; i<5; i++) {
  1259. X            arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
  1260. X        }
  1261. X        x=arg[1]; y=arg[2]; w=arg[3]; h=arg[4];
  1262. X    }
  1263. X    if( w!=-1 ) {
  1264. X        int i;
  1265. X        if ( x+w>maxwidth || y+h>maxheight ) {
  1266. X            ierror(NULL, 500);
  1267. X            return 20;
  1268. X        }
  1269. X        if( w<Win->MinWidth  ) w=Win->MinWidth;
  1270. X        if( h<Win->MinHeight ) h=Win->MinHeight;
  1271. X        if( Win->LeftEdge!=0 || Win->TopEdge!=0 )
  1272. X            MoveWindow(Win, -Win->LeftEdge, -Win->TopEdge );
  1273. X        if( Win->Width!=w || Win->Height!=h )
  1274. X            SizeWindow(Win, w-Win->Width   , h-Win->Height  );
  1275. X        if( x || y )
  1276. X            MoveWindow(Win, x, y );
  1277. X        for( i=0; i<7; i++ ) {
  1278. X            if(  Win->LeftEdge==x && Win->TopEdge==y && 
  1279. X                 Win->Width   ==w && Win->Height ==h )
  1280. X                break;
  1281. X            Delay(5);
  1282. X        }
  1283. X    } else 
  1284. X        Delay(30); /* pause 1/2 sec. before trying to print */
  1285. X
  1286. X    printf("\014");
  1287. X    return 0;
  1288. X}
  1289. X
  1290. X
  1291. Xstatic void
  1292. Xsetsystemtime(struct DateStamp *ds)
  1293. X{
  1294. X    struct timerequest tr;
  1295. X    long secs= ds->ds_Days*86400+ds->ds_Minute*60+ds->ds_Tick/TICKS_PER_SECOND;
  1296. X
  1297. X    if (OpenDevice(TIMERNAME, UNIT_VBLANK,(struct IORequest *)&tr, 0L)) {
  1298. X        fprintf(stderr,"Clock error: can't open timer device\n");
  1299. X        return;
  1300. X    }
  1301. X
  1302. X    tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  1303. X    tr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  1304. X    tr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  1305. X    tr.tr_node.io_Message.mn_ReplyPort = NULL;
  1306. X    tr.tr_node.io_Command = TR_SETSYSTIME;
  1307. X    tr.tr_time.tv_secs = secs;
  1308. X    tr.tr_time.tv_micro = 0L;
  1309. X    if (DoIO ((struct IORequest *)&tr))
  1310. X        fprintf(stderr,"Clock error: can't talk to timer device\n");
  1311. X    CloseDevice ((struct IORequest *)&tr);
  1312. X}
  1313. X
  1314. Xchar tday[10];
  1315. X
  1316. Xchar *
  1317. Xdates( struct DateStamp *dss )
  1318. X{
  1319. X    static char timestr[40];
  1320. X    char tdate[10], ttime[10];
  1321. X    struct DateTime dt;
  1322. X    struct DateStamp *myds=&(dt.dat_Stamp);
  1323. X
  1324. X    dt.dat_Format=FORMAT_DOS;
  1325. X    dt.dat_StrDay=tday;
  1326. X    dt.dat_StrDate=tdate;
  1327. X    dt.dat_StrTime=ttime;
  1328. X    dt.dat_Flags=NULL;
  1329. X    myds->ds_Days=dss->ds_Days;
  1330. X    myds->ds_Minute=dss->ds_Minute;
  1331. X    myds->ds_Tick=dss->ds_Tick;
  1332. X    StamptoStr(&dt);
  1333. X    sprintf(timestr,"%s %s\n",tdate,ttime);
  1334. X    timestr[18]=0;    /* protection against bad timestamped files */
  1335. X    return timestr;
  1336. X}
  1337. X
  1338. Xint
  1339. Xdo_date( void )
  1340. X{
  1341. X    static long stopwatch;
  1342. X    struct DateStamp dss;
  1343. X    struct DateTime dt;
  1344. X    long time;
  1345. X    int i=1;
  1346. X
  1347. X    dt.dat_Format=FORMAT_DOS;
  1348. X    if (ac==1) {
  1349. X        DateStamp(&dss);
  1350. X        time=dss.ds_Minute*6000+2*dss.ds_Tick;   /* 2 = 100/TickPerSec   */
  1351. X        if( options & 1 )
  1352. X            stopwatch=time;
  1353. X        else if( options&2 )
  1354. X            printf( "%d.%02d\n",(time-stopwatch)/100,(time-stopwatch)%100);
  1355. X        else 
  1356. X            printf("%s %s\n",tday,dates(&dss));
  1357. X    } else {
  1358. X        DateStamp(&dt.dat_Stamp);
  1359. X        for ( ; i<ac; i++) {
  1360. X            dt.dat_StrDate=NULL;
  1361. X            dt.dat_StrTime=NULL;
  1362. X            dt.dat_Flags=DTF_FUTURE;
  1363. X            if (index(av[i],':')) dt.dat_StrTime=av[i];
  1364. X                else dt.dat_StrDate=av[i];
  1365. X            if (StrtoStamp(&dt)) ierror(av[i],500);
  1366. X        }
  1367. X        setsystemtime( & (dt.dat_Stamp) );
  1368. X    }
  1369. X    return 0;
  1370. X}
  1371. END_OF_FILE
  1372. if test 30286 -ne `wc -c <'comm1.c'`; then
  1373.     echo shar: \"'comm1.c'\" unpacked with wrong size!
  1374. fi
  1375. # end of 'comm1.c'
  1376. fi
  1377. if test -f 'execom.c' -a "${1}" != "-c" ; then 
  1378.   echo shar: Will not clobber existing file \"'execom.c'\"
  1379. else
  1380. echo shar: Extracting \"'execom.c'\" \(30651 characters\)
  1381. sed "s/^X//" >'execom.c' <<'END_OF_FILE'
  1382. X/*
  1383. X * EXECOM.C
  1384. X *
  1385. X * Matthew Dillon, 10 August 1986
  1386. X *    Finally re-written.
  1387. X *
  1388. X * Version 2.07M by Steve Drew 10-Sep-87
  1389. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  1390. X * Version 5.00L by Urban Mueller 17-Feb-91
  1391. X *
  1392. X */
  1393. X
  1394. X#include "shell.h"
  1395. X
  1396. X/* execom.c */
  1397. Xstatic void preformat(char *s, char *d);
  1398. Xstatic void backtrans(char *str);
  1399. Xstatic int fcomm(char *str);
  1400. Xstatic char *exarg(char **ptr);
  1401. Xstatic void mpush_base(void);
  1402. Xstatic char *mpush(int bytes);
  1403. Xstatic void mpop_tobase(void);
  1404. Xstatic char *format_insert_string(char *str, char *from);
  1405. Xstatic int cmd_stat(char *str);
  1406. Xstatic int find_command(char *str);
  1407. Xstatic char *push_cpy(char *s);
  1408. Xstatic void exec_every(void);
  1409. Xstatic void show_usage(char *str);
  1410. Xstatic void get_opt(char **av, int *ac, int ccno);
  1411. Xstatic int checkav( int n );
  1412. X
  1413. X
  1414. Xint has_wild = 0;                 /* set if any arg has wild card */
  1415. Xchar *LastCommand;
  1416. X
  1417. Xstruct COMMAND {
  1418. X    int (*func)();
  1419. X    short minargs;
  1420. X    short stat;
  1421. X    int val;
  1422. X    char *name;
  1423. X    char *options;
  1424. X    char *usage;
  1425. X};
  1426. X
  1427. Xextern int do_basename(), do_tackon();
  1428. Xextern int do_fltupper(), do_fltlower(), do_linecnt();
  1429. Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen();
  1430. Xextern int do_fornum(), do_forline(), do_exec();
  1431. Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
  1432. Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
  1433. Xextern int do_open(), do_close(), do_fileslist(), do_htype(), do_aget();
  1434. Xextern int do_run(), do_number(), do_assign(), do_join();
  1435. Xextern int do_quit(), do_set_var(), do_unset_var();
  1436. Xextern int do_echo(), do_source(), do_mv(), do_addbuffers();
  1437. Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
  1438. Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
  1439. Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
  1440. Xextern int do_input(), do_ver(), do_sleep(), do_help();
  1441. Xextern int do_strhead(), do_strtail(), do_relabel();
  1442. Xextern int do_copy(), do_date(), do_protect(), do_ps();
  1443. Xextern int do_forever(), do_abortline(), do_strings(), do_touch();
  1444. Xextern int do_window(), do_search(), do_filenote(), do_rxrec(), do_rxsend();
  1445. Xextern int do_ascii(), do_whereis(), do_sort(), do_qcd(), do_usage();
  1446. Xextern int do_uniq(), do_man(), do_head(), do_tee(), do_menu(), do_readfile();
  1447. Xextern int do_rxreturn(), do_split(), do_which(), do_class();
  1448. Xextern int do_action(), do_keymap();
  1449. X
  1450. X#define ST_COND   0x01
  1451. X#define ST_NORED  0x02
  1452. X#define ST_NOEXP  0x04
  1453. X#define ST_AV     0x08 /* delimit args within a variable */
  1454. X#define ST_FUNC   0x10
  1455. X
  1456. X#define COND  ST_COND
  1457. X#define NORED ST_NORED
  1458. X#define NOEXP ST_NOEXP
  1459. X#define AV    ST_AV
  1460. X#define FUNC  ST_FUNC
  1461. X
  1462. X#define ALIAS LEVEL_ALIAS
  1463. X#define SET   LEVEL_SET
  1464. X
  1465. XBPTR   OldCin;
  1466. X
  1467. Xstruct COMMAND Command[] = {
  1468. X do_run,       0,   AV,     0, "\001",       NULL, NULL, /* may call do_source, do_cd */
  1469. X do_abortline, 0,    0,     0, "abortline",  NULL, "",
  1470. X do_action,    2,    0,     9, "action",     "av", "action file [args]",
  1471. X do_addbuffers,2,    0,     0, "addbuffers", NULL, "{drive bufs}",
  1472. X do_set_var,   0,    0, ALIAS, "alias",      NULL, "[name [string] ]",/* uses avline */
  1473. X do_ascii,     0,    0,     0, "ascii",      "oh", "-oh [string]",
  1474. X do_aset,      1,    0,     0, "aset",       NULL, "name value",
  1475. X do_assign,    0,    0,     0, "assign",     "ln", ",logical,-ln {logical physical}",
  1476. X do_basename,  2, FUNC,     0, "basename",   NULL, "var path",
  1477. X do_cat,       0,    0,     0, "cat",        "n",  "-n [file file...]",
  1478. X do_cd,        0,    0,     0, "cd",         "g",  "[path],-g path...path",
  1479. X do_class,     0,   AV,     0, "class",      "n",  "-n name {type=param} \"actions\" {action=command}",
  1480. X do_close,     0,    0,     0, "close",      NULL, "filenumber",
  1481. X do_copy,      1,    0,     0, "copy",       "rudpf","-rudpf file file,-ud file...file dir,-ud dir...dir dir",
  1482. X do_copy,      1,    0,     0, "cp",         "rudpf","-rudpf file file,-ud file...file dir,-ud dir...dir dir",
  1483. X do_date,      0,    0,     0, "date",       "sr", "-sr [date/time]",
  1484. X do_inc,       1,    0,    -1, "dec",        NULL, "varname [step]",
  1485. X do_rm,        0,    0,     0, "delete",     "rp", "-pr file...file",
  1486. X do_dir,       0,NOEXP,     0, "dir",        "sfdcnhltbuikqavo","-abcdfhiklnoqstuv [path...path]",
  1487. X do_diskchange,1,    0,     0, "diskchange", NULL, "drive",
  1488. X do_echo,      0,   AV,     0, "echo",       "ne", "-ne string",
  1489. X do_if,        0, COND,     1, "else",       NULL, "",
  1490. X do_if,        0, COND,     2, "endif",      NULL, "",
  1491. X do_exec,      1,    0,     0, "exec",       NULL, "command",
  1492. X do_fault,     1,    0,     0, "fault",      NULL, "error",
  1493. X do_filenote,  1,    0,     0, "filenote",   "s",  "file...file note,-s file...file",
  1494. X do_fileslist, 0,    0,     0, "flist",      NULL, "",
  1495. X do_fltlower,  0,    0,     0, "fltlower",   NULL, "<in >out",
  1496. X do_fltupper,  0,    0,     0, "fltupper",   NULL, "<in >out",
  1497. X do_foreach,   3,NORED,     0, "foreach",    "v",  "-v varname ( string ) command",
  1498. X do_forever,   1,NORED,     0, "forever",    NULL, "command",
  1499. X do_forline,   3,NORED,     0, "forline",    NULL, "var filename command",
  1500. X do_fornum,    4,NORED,     0, "fornum",     "vs", "-vs var n1 n2 command",
  1501. X do_getenv,    1, FUNC,     0, "getenv",     NULL, "shellvar envvar",
  1502. X do_goto,      1,    0,     0, "goto",       NULL, "label",
  1503. X do_head,      1,    0,     0, "head",       NULL, "filename [num]",
  1504. X do_help,      0,    0,     0, "help",       NULL, "",
  1505. X do_history,   0,    0,     0, "history",    NULL, "[partial_string]",
  1506. X do_howmany,   0,    0,     0, "howmany",    NULL, "",
  1507. X do_htype,     1,    0,     0, "htype",      "r",  "-r file...file",
  1508. X do_if,        1,COND|NORED,0, "if",         "rftmdvn","-n arg cond arg,-n arg,-nf file,-nd dir -nm,-nt file...file,-nr rpn_expr,-v varname",
  1509. X do_inc,       1,    0,     1, "inc",        NULL, "varname [step]",
  1510. X do_info,      0,    0,     0, "info",       NULL, "[drive...drive]",
  1511. X do_input,     1,    0,     0, "input",      "sr", "-rs var...var",
  1512. X do_join,      2,    0,     1, "join",       "r",  "-r file...file",
  1513. X do_keymap,    1,    0,     0, "keymap",     "n",  "-n number {key=function}",
  1514. X do_label,     1, COND,     0, "label",      NULL, "name",
  1515. X do_linecnt,   0,    0,     0, "linecnt",    NULL, "<in >out",
  1516. X do_dir,       0,NOEXP,     0, "ls",         "sfdcnhltbuikqav","-abcdfhiklnqstuv [path...path]",
  1517. X do_man,       0,    0,     0, "man",        NULL, "command...command",
  1518. X do_mkdir,     0,    0,     0, "md",         NULL, "name...name",
  1519. X do_mem,       0,    0,     0, "mem",        "cfqsr","-cfqsr",
  1520. X do_menu,      0,    0,     0, "menu",       "n",  "-n [title item...item]",
  1521. X do_mkdir,     0,    0,     0, "mkdir",      NULL, "name...name",
  1522. X do_mv,        2,    0,     0, "mv",         NULL, "from to,from...from todir",
  1523. X do_open,      3,    0,     0, "open",       NULL, "file mode number",
  1524. X do_path,      0,    0,     0, "path",       "r",  "-r [dir...dir]",
  1525. X do_pri,       2,    0,     0, "pri",        NULL, "clinumber pri,0 pri",
  1526. X do_protect,   2,    0,     0, "protect",    NULL, "file...file flags",
  1527. X do_ps,        0,    0,     0, "ps",         "le", "-el [commandname...commandname]",
  1528. X do_pwd,       0,    0,     0, "pwd",        NULL, "",
  1529. X do_qsort,     0,    0,     0, "qsort",      NULL, "<in >out",
  1530. X do_quit,      0,NORED,     0, "quit",       NULL, "",
  1531. X do_truerun,   1,NORED,     1, "rback",      NULL, "command",
  1532. X do_mv,        2,    0,     0, "rename",     NULL, "from to,from...from todir",
  1533. X do_readfile,  1,    0,     0, "readfile",   NULL, "varname [filename]",
  1534. X do_relabel,   2,    0,     0, "relabel",    NULL, "drive name",
  1535. X do_resident,  0,    0,     0, "resident",   "ard",",-ard file...file",
  1536. X do_return,    0,    0,     0, "return",     NULL, "[n]",
  1537. X do_rm,        0,    0,     0, "rm",         "rp", "-rp file...file",
  1538. X do_rpn,       0,NOEXP,     0, "rpn",        NULL, "expression",
  1539. X do_rxrec,     0,    0,     0, "rxrec",      NULL, "[portname]",
  1540. X do_rxsend,    2,    0,     0, "rxsend",     "rl", "-lc portname string",
  1541. X do_truerun,   1,NORED,     0, "run",        NULL, "command",
  1542. X do_search,    2,    0,     0, "search",     "rcwneqvbfalo","-abceflnoqrvw file...file string",
  1543. X do_set_var,   0,   AV,   SET, "set",        NULL, "[name [string] ]",
  1544. X do_setenv,    2,    0,     0, "setenv",     NULL, "var value",
  1545. X do_sleep,     0,    0,     0, "sleep",      NULL, "timeout",
  1546. X do_split,     1,    0,     0, "split",      NULL, "srcvar dstvar...dstvar",
  1547. X do_source,    1,NORED|AV,  0, "source",     NULL, "file", /* uses avline */
  1548. X do_stack,     0,    0,     0, "stack",      NULL, "[bytes]",
  1549. X do_strhead,   3, FUNC,     0, "strhead",    NULL, "varname breakchar string",
  1550. X do_strings,   1,    0,     0, "strings",    "r",  "-r file...file minlength",
  1551. X do_strleft,   3, FUNC,     0, "strleft",    NULL, "varname string n",
  1552. X do_strlen,    2, FUNC,     0, "strlen",     NULL, "varname string",
  1553. X do_strmid,    3, FUNC,     0, "strmid",     NULL, "varname string n1 [n2]",
  1554. X do_strright,  3, FUNC,     0, "strright",   NULL, "varname string n",
  1555. X do_strtail,   3, FUNC,     0, "strtail",    NULL, "varname breakchar string",
  1556. X do_tackon,    3, FUNC,     0, "tackon",     NULL, "var pathname filename",
  1557. X do_head,      1,    0,     1, "tail",       NULL, "filename [num]",
  1558. X do_tee,       0,    0,     0, "tee",        NULL, "<in >out",
  1559. X do_touch,     0,    0,     0, "touch",      NULL, "file...file",
  1560. X do_truncate,  0,    0,     0, "truncate",   NULL, "<in >out",
  1561. X do_cat,       0,    0,     0, "type",       NULL, "-n [file...file]",
  1562. X do_unset_var, 0,    0, ALIAS, "unalias",    NULL, "name...name",
  1563. X do_uniq,      0,    0,     0, "uniq",       NULL, "<in >out",
  1564. X do_unset_var, 0,    0,   SET, "unset",      NULL, "name...name",
  1565. X do_usage,     0,    0,     0, "usage",      NULL, "[command...command]",
  1566. X do_ver,       0,    0,     0, "version",    NULL, "",
  1567. X do_waitport,  1,    0,     0, "waitforport",NULL, "portname [seconds]",
  1568. X do_whereis,   1,NOEXP,     0, "whereis",    "r",  "-r file [path...path]",
  1569. X do_window,    0,NOEXP,     0, "window",     "slfbaq","-slfbaq",
  1570. X NULL,         0,    0,     0, NULL,         NULL, NULL,
  1571. X};
  1572. X
  1573. X
  1574. X/* do_which,     1,    0,     0, "which",      NULL, "command", */
  1575. X
  1576. Xstatic char elast;        /* last end delimeter */
  1577. Xchar Cin_ispipe, Cout_ispipe;
  1578. X
  1579. X#ifdef isalphanum
  1580. Xchar isalph[256];
  1581. X#endif
  1582. X
  1583. Xint
  1584. Xexec_command( char *base )
  1585. X{
  1586. X    char *scr;
  1587. X    char buf[32];
  1588. X
  1589. X    if (!H_stack && S_histlen>1) {
  1590. X        add_history(base);
  1591. X        sprintf(buf, "%d", H_tail_base + H_len);
  1592. X        set_var(LEVEL_SET, v_histnum, buf);
  1593. X    }
  1594. X    scr = malloc((strlen(base) << 2) + 2);
  1595. X    preformat(base, scr);
  1596. X    return (fcomm(scr) ? -1 : 1);
  1597. X}
  1598. X
  1599. X#ifndef isalphanum
  1600. Xisalphanum( char c )
  1601. X{
  1602. X    return (
  1603. X        (c >= 'a' && c <= 'z') ||
  1604. X        (c >= 'A' && c <= 'Z') ||
  1605. X        (c >= '0' && c <= '9') ||
  1606. X        (c == '_')
  1607. X    );
  1608. X}
  1609. X#endif
  1610. X
  1611. X#define HOT_GAP    0x80
  1612. X#define HOT_BLANK  0x81
  1613. X#define HOT_STAR   0x82
  1614. X#define HOT_QUES   0x83
  1615. X#define HOT_EXCL   0x84
  1616. X#define HOT_SEMI   0x85
  1617. X#define HOT_PIPE   0x86
  1618. X#define HOT_DOLLAR 0x87
  1619. X#define HOT_IN     0x88
  1620. X#define HOT_OUT    0x89
  1621. X#define HOT_BSLASH 0x8a
  1622. X#define HOT_APOSTR 0x8b
  1623. X#define HOT_USAGE  0x8c
  1624. X#define HOT_SBLANK 0xA0
  1625. X
  1626. X
  1627. Xstatic void
  1628. Xpreformat( char *s, char *d )
  1629. X{
  1630. X    int qm, i;
  1631. X
  1632. X    qm = 0;
  1633. X    while (*s == ' ' || *s == 9) ++s;
  1634. X    if      (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
  1635. X    else if (*s == '~'  ) { *d++=HOT_APOSTR; s++; }
  1636. X
  1637. X    while (*s) {
  1638. X        if (qm ) {
  1639. X            while( *s && *s != '\"' && *s != '\\')
  1640. X                *d++ = *s++;
  1641. X            if( !*s ) break;
  1642. X        }
  1643. X        switch (*s) {
  1644. X        case ' ':
  1645. X        case 9:
  1646. X            *d++ = HOT_BLANK;
  1647. X            while (*s == ' ' || *s == 9) ++s;
  1648. X            if      (*s == '~'  ) { *d++=HOT_APOSTR; s++; }
  1649. X            else if (*s == 0 || *s == '|' || *s == ';') --d;
  1650. X            break;
  1651. X        case '*':
  1652. X            *d++ = HOT_GAP;
  1653. X            *d++ = HOT_STAR;
  1654. X            ++s;
  1655. X            break;
  1656. X        case '?':
  1657. X            *d++ = HOT_GAP;
  1658. X            *d++ = HOT_QUES;
  1659. X            ++s;
  1660. X            break;
  1661. X        case '!':
  1662. X            *d++ = HOT_EXCL;
  1663. X            ++s;
  1664. X            break;
  1665. X        case '#':
  1666. X            *d++ = '\0';
  1667. X            while (*s) ++s;
  1668. X            break;
  1669. X        case ';':
  1670. X        case '|':
  1671. X            *d++= (*s++==';') ? HOT_SEMI : HOT_PIPE;
  1672. X            while (*s == ' ' || *s == 9) ++s;
  1673. X            if    (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
  1674. X            break;
  1675. X        case '\\':
  1676. X            if( (i=*++s-'0')>=0 && i<=7 ) {
  1677. X                if( *++s>='0' && *s<='7' ) {
  1678. X                    i= 8*i + *s++-'0';
  1679. X                    if( *s>='0' && *s<='7' )
  1680. X                        i= 8*i + *s++-'0';
  1681. X                }
  1682. X                *d++ = i;
  1683. X            } else {
  1684. X                *d++ = *s;
  1685. X                if (*s) ++s;
  1686. X            }
  1687. X            break;
  1688. X        case '\"':
  1689. X            qm = 1 - qm;
  1690. X            ++s;
  1691. X            break;
  1692. X        case '^':
  1693. X            *d++ = *++s & 0x1F;
  1694. X            if (*s) ++s;
  1695. X            break;
  1696. X        case '<':
  1697. X            *d++ = HOT_IN;
  1698. X            ++s;
  1699. X            break;
  1700. X        case '>':
  1701. X            *d++ = HOT_OUT;
  1702. X            ++s;
  1703. X            break;
  1704. X        case '$': /* search end of var name and place false space */
  1705. X            *d++ = HOT_GAP;
  1706. X            *d++ = HOT_DOLLAR;
  1707. X            ++s;
  1708. X            while (isalphanum(*s)) *d++ = *s++;
  1709. X            *d++ = HOT_GAP;
  1710. X            break;
  1711. X        default:
  1712. X            *d++ = *s++;
  1713. X            break;
  1714. X        }
  1715. X    }
  1716. X    *d++=0;
  1717. X    *d=0;
  1718. X    if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
  1719. X}
  1720. X
  1721. Xstatic void
  1722. Xbacktrans( char *str )
  1723. X{
  1724. X    while( *str ) {
  1725. X        while( *(signed char *)str>0 ) str++;
  1726. X        if( !*str ) break;
  1727. X        switch( *str) {
  1728. X            case HOT_GAP   : *str++=0;    break;
  1729. X            case HOT_BLANK : *str++=' ';  break;
  1730. X            case HOT_STAR  : *str++='*';  break;
  1731. X            case HOT_QUES  : *str++='?';  break;
  1732. X            case HOT_EXCL  : *str++='!';  break;
  1733. X            case HOT_SEMI  : *str++=';';  break;
  1734. X            case HOT_PIPE  : *str++='|';  break;
  1735. X            case HOT_DOLLAR: *str++='$';  break;
  1736. X            case HOT_IN    : *str++='<';  break;
  1737. X            case HOT_OUT   : *str++='>';  break;
  1738. X            case HOT_BSLASH: *str++='\\'; break;
  1739. X            case HOT_APOSTR: *str++='~';  break;
  1740. X            default        : str++;       break;
  1741. X        }
  1742. X    }
  1743. X}
  1744. X
  1745. X
  1746. Xvoid *
  1747. Xmymalloc( int len )
  1748. X{
  1749. X    return malloc(len);
  1750. X}
  1751. X
  1752. Xextern BPTR extOpen();
  1753. X
  1754. X/*
  1755. X * process formatted string.  ' ' is the delimeter.
  1756. X *
  1757. X *    0: check '\0': no more, stop, done.
  1758. X *    1: check $.     if so, extract, format, insert
  1759. X *    2: check alias. if so, extract, format, insert. goto 1
  1760. X *    3: check history or substitution, extract, format, insert. goto 1
  1761. X *
  1762. X *    4: assume first element now internal or disk based command.
  1763. X *
  1764. X *    5: extract each ' ' or 0x80 delimited argument and process, placing
  1765. X *       in av[] list (except 0x80 args appended).  check in order:
  1766. X *
  1767. X *             '$'         insert string straight
  1768. X *             '>'         setup stdout
  1769. X *             '>>'        setup stdout flag for append
  1770. X *             '<'         setup stdin
  1771. X *             '*' or '?'  do directory search and insert as separate args.
  1772. X *
  1773. X *             ';' 0 '|'   end of command.  if '|' setup stdout
  1774. X *                          -execute command, fix stdin and out (|) sets
  1775. X *                           up stdin for next guy.
  1776. X */
  1777. X
  1778. X
  1779. Xint
  1780. Xfcomm( char *str )
  1781. X{
  1782. X    static int alias_count;
  1783. X    int p_alias_count;
  1784. X    char *istr, *nextstr, *command;
  1785. X    char *pend_alias;
  1786. X    int err;
  1787. X
  1788. X    ++alias_count;
  1789. X
  1790. Xentry:
  1791. X    p_alias_count = 0;
  1792. X    pend_alias = NULL;
  1793. X    err=0;
  1794. X    has_wild = 0;
  1795. X
  1796. X    mpush_base();
  1797. X    if (*str == 0)
  1798. X        goto done1;
  1799. Xstep1:
  1800. X    if (alias_count >= MAXALIAS || p_alias_count >= MAXALIAS) {
  1801. X        fprintf(stderr,"Alias Loop\n");
  1802. X        err = 20;
  1803. X        goto done1;
  1804. X    }
  1805. X
  1806. X    istr = NULL;
  1807. X    if ( *str == HOT_BSLASH )
  1808. X        memmove( str, str+1, strlen(str));
  1809. X    else 
  1810. X        istr = get_var (LEVEL_ALIAS, str);  /* only if not \command */
  1811. X
  1812. X    if (istr) {
  1813. X        p_alias_count++;
  1814. X        if (*istr == '%' || *istr=='*') {
  1815. X            pend_alias = istr;
  1816. X        } else {
  1817. X            str = format_insert_string(str, istr );
  1818. X            goto step1;
  1819. X        }
  1820. X    }
  1821. X
  1822. X    if (*str == HOT_EXCL) {
  1823. X        char *p, c;                     /* fix to allow !cmd1;!cmd2 */
  1824. X        for(p = str; *p && *p != HOT_SEMI ; ++p);
  1825. X        c = *p;
  1826. X        *p = '\0';
  1827. X        istr = get_history(str,1);
  1828. X        *p = c;
  1829. X        replace_head(istr);
  1830. X        str = format_insert_string(str, istr );
  1831. X        goto step1;
  1832. X    }
  1833. X
  1834. X    nextstr = str;
  1835. X    command = exarg(&nextstr);
  1836. X    if (*command == 0)
  1837. X        goto done0;
  1838. X    if (pend_alias == 0) {
  1839. X        if (cmd_stat(command) & ST_COND)
  1840. X            goto skipgood;
  1841. X    }
  1842. X
  1843. X    if (disable || forward_goto) {
  1844. X        while (elast && elast != HOT_SEMI && elast != HOT_PIPE)
  1845. X            exarg(&nextstr);
  1846. X        goto done0;
  1847. X    }
  1848. Xskipgood:
  1849. X    {
  1850. X        char *arg, *ptr;
  1851. X        short redir;
  1852. X        short doexpand;
  1853. X        short cont;
  1854. X        short inc;
  1855. X
  1856. X        ac = 1;
  1857. X        av[0] = command;
  1858. X        backtrans( av[0] );
  1859. Xstep5:                                          /* ac = nextac */
  1860. X        if (!elast || elast == HOT_SEMI || elast == HOT_PIPE)
  1861. X            goto stepdone;
  1862. X
  1863. X        av[ac] = NULL;
  1864. X        cont = 1;
  1865. X        doexpand = redir = inc = 0;
  1866. X
  1867. X        while (cont && elast) {
  1868. X            int cstat = cmd_stat(command);
  1869. X
  1870. X            ptr = exarg(&nextstr);
  1871. X            inc = 1;
  1872. X            arg = "";
  1873. X            cont = (elast == 0x80);
  1874. X            switch (*ptr) {
  1875. X            case HOT_IN:
  1876. X                redir = -2;
  1877. X            case HOT_OUT:
  1878. X                if (cstat & (ST_NORED | ST_COND)) {     /* don't extract   */
  1879. X                    redir = 0;                          /* <> stuff if its */
  1880. X                    arg = ptr;                          /* external cmd.   */
  1881. X                    break;
  1882. X                }
  1883. X                ++redir;
  1884. X                arg = ptr + 1;
  1885. X                if (*arg == HOT_OUT) {
  1886. X                    redir = 2;        /* append >> */
  1887. X                    ++arg;
  1888. X                }
  1889. X                cont = 1;
  1890. X                break;
  1891. X            case HOT_DOLLAR:
  1892. X                /* restore args if from set command or pend_alias */
  1893. X                if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
  1894. X                    char *pe, sv;
  1895. X                    while (pe = index(arg,0xA0)) {
  1896. X                        sv = *pe;
  1897. X                        *pe = '\0';
  1898. X                        checkav(1);
  1899. X                        av[ac++] = push_cpy(arg);
  1900. X                        *pe = sv;
  1901. X                        av[ac] = NULL;
  1902. X                        arg = pe+1;
  1903. X                    }
  1904. X                } else
  1905. X                    arg = ptr;
  1906. X                break;
  1907. X            case HOT_APOSTR:
  1908. X                if ((arg = get_var(LEVEL_SET, v_lcd)) != NULL) {
  1909. X                    if( ptr[1] ) {
  1910. X                        strcpy(Buf,arg);
  1911. X                        appendslash(Buf);
  1912. X                        strcat(Buf,ptr+1);
  1913. X                        arg=Buf;
  1914. X                    }
  1915. X                } else
  1916. X                    arg = ptr;
  1917. X                break;
  1918. X
  1919. X            case HOT_STAR:
  1920. X            case HOT_QUES:
  1921. X                if((cstat & ST_NOEXP) == 0 && !(pend_alias && *istr=='*'))
  1922. X                    if(ac==1&&(av[1]==NULL||!*av[1])&& *ptr==HOT_QUES&& !ptr[1])
  1923. X                        ;
  1924. X                    else 
  1925. X                        doexpand = 1;
  1926. X                arg = ptr;
  1927. X                break;
  1928. X            default:
  1929. X                arg = ptr;
  1930. X                break;
  1931. X            }
  1932. X
  1933. X            /* Append arg to av[ac] */
  1934. X
  1935. X            if (av[ac]) {
  1936. X                char *old = av[ac];
  1937. X                av[ac] = mpush(strlen(arg)+strlen(av[ac]));
  1938. X                strcpy(av[ac], old);
  1939. X                strcat(av[ac], arg);
  1940. X            } else
  1941. X                av[ac] = push_cpy(arg);
  1942. X
  1943. X            if (elast != 0x80)
  1944. X                break;
  1945. X        }
  1946. X
  1947. X        /* process expansion */
  1948. X
  1949. X        backtrans( av[ac] );
  1950. X        if (doexpand) {
  1951. X            char **eav, **ebase;
  1952. X            int eac;
  1953. X            has_wild = 1;
  1954. X            eav = ebase = expand(av[ac], &eac);
  1955. X            inc = 0;
  1956. X            if (eav) {
  1957. X                if( checkav( eac ) ) {
  1958. X                    ierror (NULL, 506);
  1959. X                    err = 1;
  1960. X                } else {
  1961. X                    QuickSort(eav, eac);
  1962. X                    for (; eac; --eac, ++eav)
  1963. X                    av[ac++] = push_cpy(*eav);
  1964. X                }
  1965. X                free_expand (ebase);
  1966. X            }
  1967. X        } else if( av[ac][0]==')' ) {
  1968. X            int i;
  1969. X            char *pe, sv;
  1970. X            for( i=ac-1; i>0; i-- )
  1971. X                if( *av[i]=='@' )
  1972. X                    break;
  1973. X            if( i>0 && av[i][strlen(av[i])-1]=='(' ) {
  1974. X                extern int exec_fn_err;
  1975. X                char *exec_function();
  1976. X                char *avi=av[i], *last=av[ac];
  1977. X                av[i]=v_value; av[ac]=NULL;
  1978. X                arg=exec_function( avi+1, av+i, ac-i );
  1979. X                av[i]=avi;     av[ac]=last;
  1980. X                inc=0;
  1981. X                if( exec_fn_err<0 )
  1982. X                    ac++;
  1983. X                else if( exec_fn_err>0 || !arg )
  1984. X                    ac=i, av[ac++]="";
  1985. X                else {
  1986. X                    ac=i;
  1987. X                    while (pe = index(arg,0xA0)) {
  1988. X                        sv = *pe;
  1989. X                        *pe = '\0';
  1990. X                        checkav( 2 );
  1991. X                        av[ac++] = push_cpy(arg);
  1992. X                        *pe = sv;
  1993. X                        arg= pe+1;
  1994. X                    }
  1995. X                    av[ac] = mpush(strlen(arg)+strlen(last+1)+4);
  1996. X                    strcpy(av[ac],arg);
  1997. X                    strcat(av[ac++], last+1 );
  1998. X                }
  1999. X            }
  2000. X        }
  2001. X
  2002. X
  2003. X        /* process redirection  */
  2004. X
  2005. X        if (redir && !err) {
  2006. X            char *file = (doexpand) ? av[--ac] : av[ac];
  2007. X
  2008. X            if (redir < 0)
  2009. X                Cin_name = file;
  2010. X            else {
  2011. X                Cout_name = file;
  2012. X                Cout_append = (redir == 2);
  2013. X            }
  2014. X            inc = 0;
  2015. X        }
  2016. X
  2017. X        /* check elast for space */
  2018. X
  2019. X        if (inc) {
  2020. X            ++ac;
  2021. X            if (ac + 2 > MAXAV) {
  2022. X                ierror (NULL, 506);
  2023. X                err = 1;                /* error condition */
  2024. X                elast = 0;              /* don't process any more arguemnts */
  2025. X            }
  2026. X        }
  2027. X        if (elast == HOT_BLANK)
  2028. X            goto step5;
  2029. X    }
  2030. Xstepdone:
  2031. X    av[ac] = NULL;
  2032. X
  2033. X    /* process pipes via files */
  2034. X
  2035. X    if (elast == HOT_PIPE && !err) {
  2036. X        static int which;             /* 0 or 1 in case of multiple pipes */
  2037. X        which = 1 - which;
  2038. X        Cout_name = (which) ? Pipe1 : Pipe2;
  2039. X        Cout_ispipe = 1;
  2040. X    }
  2041. X
  2042. X
  2043. X    if (err)
  2044. X        goto done0;
  2045. X
  2046. X    {
  2047. X        int i;
  2048. X        char save_elast;
  2049. X        char *avline;
  2050. X        char delim = ' ';
  2051. X        char *larg=av[ac-1];
  2052. X
  2053. X        if( *larg && larg[strlen(larg)-1]=='&' ) {
  2054. X            memmove( av+1, av, (ac-1)*sizeof(*av));
  2055. X            command=av[0]="rback";
  2056. X            if( strlen(larg)>1 )
  2057. X                larg[strlen(larg)-1]=0, ac++;
  2058. X        }
  2059. X        save_elast = elast;
  2060. X        if (pend_alias || (cmd_stat(command) & ST_AV))
  2061. X            delim = 0xA0;
  2062. X        avline = compile_av(av,((pend_alias) ? 1 : 0), ac, delim, 0);
  2063. X
  2064. X        if (pend_alias) {                               /* special % alias */
  2065. X            char *ptr, *scr, *varname, *val=avline, *gap;
  2066. X            ptr=pend_alias;
  2067. X            do {                                        /* set all args    */
  2068. X                for ( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
  2069. X                if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0;
  2070. X                set_var( LEVEL_SET, varname, val );
  2071. X                val= gap ? gap+1 : "";
  2072. X            } while( *ptr=='%' );
  2073. X            free (avline);
  2074. X
  2075. X            scr = malloc((strlen(ptr) << 2) + 2);
  2076. X            preformat (ptr, scr);
  2077. X            fcomm (scr);
  2078. X            ptr=pend_alias;
  2079. X            do {                                        /* unset all args  */
  2080. X                for ( varname=++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
  2081. X                unset_var( LEVEL_SET, varname );
  2082. X            } while( *ptr=='%' );
  2083. X            unset_var (LEVEL_SET, pend_alias + 1);
  2084. X        } else {                                        /* normal command  */
  2085. X            int ccno;
  2086. X            BPTR  oldcin  = Myprocess->pr_CIS;
  2087. X            BPTR  oldcout = Myprocess->pr_COS;
  2088. X            char *Cin_buf;
  2089. X            struct FileHandle *ci;
  2090. X            long oldbuf;
  2091. X
  2092. X            OldCin=oldcin;
  2093. X            fflush(stdout);
  2094. X            LastCommand=command;
  2095. X            ccno = find_command ( command);
  2096. X            if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  2097. X                if (Cin_name) {
  2098. X                    if ((Cin = (long)extOpen(Cin_name,1005L)) == 0) {
  2099. X                        ierror (NULL, 504);
  2100. X                        err = 1;
  2101. X                        Cin_name = NULL;
  2102. X                    } else {
  2103. X                        Myprocess->pr_CIS = DEVTAB(stdin) = Cin;
  2104. X                        ci = (struct FileHandle *)(((long)Cin)<<2);
  2105. X                        Cin_buf = AllocMem(202L, MEMF_PUBLIC);
  2106. X                        oldbuf = ci->fh_Buf;
  2107. X                        if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
  2108. X                            ci->fh_Buf = (long)Cin_buf>>2;
  2109. X                    }
  2110. X                }
  2111. X                if (Cout_name) {
  2112. X                    if (Cout_append && (Cout =(long)extOpen(Cout_name,1005L))) {
  2113. X                        Seek(Cout, 0L, 1L);
  2114. X                    } else {
  2115. X                        Cout = (long)extOpen(Cout_name,1006L);
  2116. X                    }
  2117. X                    if (Cout == NULL) {
  2118. X                        err = 1;
  2119. X                        ierror (NULL, 504);
  2120. X                        Cout_name = NULL;
  2121. X                        Cout_append = 0;
  2122. X                    } else {
  2123. X                        Myprocess->pr_COS = DEVTAB(stdout) = Cout;
  2124. X                    }
  2125. X                }
  2126. X            }
  2127. X            if (ac < Command[ccno].minargs + 1) {
  2128. X                show_usage( NULL );
  2129. X                err = -1;
  2130. X            } else if (!err) {
  2131. X                int (*func)(char*,int)=Command[ccno].func;
  2132. X                get_opt( av, &ac, ccno );
  2133. X                i=0;
  2134. X                if( ccno>0 && ac>1 && !strcmp(av[1],"?") )
  2135. X                    show_usage(avline);
  2136. X                else 
  2137. X                    i = (*func)(avline, Command[ccno].val);
  2138. X                fflush(stderr);
  2139. X                if (i < 0)
  2140. X                    i = 20;
  2141. X                err = i;
  2142. X            }
  2143. X            free (avline);
  2144. X            if (E_stack == 0 && Lastresult != err) {
  2145. X                Lastresult = err;
  2146. X                seterr();
  2147. X            }
  2148. X            if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  2149. X                if (Cin_name) {
  2150. X                    ci->fh_Buf = oldbuf;
  2151. X                    fflush(stdin);
  2152. X                    clearerr(stdin);
  2153. X#ifdef AZTEC_C
  2154. X                    stdin->_bp=stdin->_bend;
  2155. X#else
  2156. X                    stdin->_rcnt=stdin->_wcnt;
  2157. X#endif
  2158. X                    extClose(Cin);
  2159. X                    FreeMem(Cin_buf, 202L);
  2160. X                }
  2161. X                if (Cout_name) {
  2162. X                    fflush(stdout);
  2163. X                    clearerr(stdout);
  2164. X#ifdef AZTEC_C
  2165. X                    stdout->_flags &= ~_IODIRTY;    /* because of nil: device */
  2166. X#endif
  2167. X                    extClose(Cout);
  2168. X                    Cout_append = 0;
  2169. X                }
  2170. X            }
  2171. X            Myprocess->pr_CIS = DEVTAB(stdin)  = oldcin;
  2172. X            Myprocess->pr_COS = DEVTAB(stdout) = oldcout;
  2173. X        }
  2174. X
  2175. X        if (Cin_ispipe && Cin_name)
  2176. X            DeleteFile(Cin_name);
  2177. X        if (Cout_ispipe) {
  2178. X            Cin_name = Cout_name;         /* ok to assign.. static name */
  2179. X            Cin_ispipe = 1;
  2180. X        } else {
  2181. X            Cin_name = NULL;
  2182. X        }
  2183. X        Cout_name = NULL;
  2184. X        Cout_ispipe = 0;
  2185. X        elast = save_elast;
  2186. X    }
  2187. X    mpop_tobase();                      /* free arguments   */
  2188. X    mpush_base();                       /* push dummy base  */
  2189. X
  2190. Xdone0:
  2191. X    {
  2192. X        char *exc;
  2193. X        if (err && E_stack == 0) {
  2194. X            exc = get_var(LEVEL_SET, v_except);
  2195. X            if (err >= ((exc)?atoi(exc):1)) {
  2196. X                if (exc) {
  2197. X                    ++H_stack, ++E_stack;
  2198. X                    a0tospace(exc);
  2199. X                    exec_command(exc);
  2200. X                    --E_stack, --H_stack;
  2201. X                } else {
  2202. X                    Exec_abortline = 1;
  2203. X                }
  2204. X            }
  2205. X        }
  2206. X        if (elast != 0 && Exec_abortline == 0) {
  2207. X            memmove( str, nextstr, strlen(nextstr)+1 );
  2208. X            goto entry;
  2209. X        }
  2210. X        Exec_abortline = 0;
  2211. X        if (Cin_name)
  2212. X            DeleteFile(Cin_name);
  2213. X        Cin_name = NULL;
  2214. X        Cin_ispipe = 0;
  2215. X    }
  2216. Xdone1:
  2217. X    mpop_tobase();
  2218. X    free(str);
  2219. X    --alias_count;
  2220. X    return err;                      /* TRUE = error occured    */
  2221. X}
  2222. X
  2223. X
  2224. Xstatic char *
  2225. Xexarg(ptr)
  2226. Xchar **ptr;
  2227. X{
  2228. X    char *end, *start;
  2229. X
  2230. X    start = end = *ptr;
  2231. X    while ( *(signed char *)end>0 || *end && *end != 0x80 &&
  2232. X             *end != HOT_SEMI &&  *end != HOT_PIPE && *end != HOT_BLANK)
  2233. X        ++end;
  2234. X    elast = *end;
  2235. X    *end = '\0';
  2236. X    *ptr = end + 1;
  2237. X    return start;
  2238. X}
  2239. X
  2240. Xstatic char **Mlist;
  2241. X
  2242. Xstatic void
  2243. Xmpush_base()
  2244. X{
  2245. X    char *str;
  2246. X
  2247. X    str = malloc(5);
  2248. X    *(char ***)str = Mlist;
  2249. X    str[4] = 0;
  2250. X    Mlist = (char **)str;
  2251. X}
  2252. X
  2253. Xstatic char *
  2254. Xmpush(bytes)
  2255. X{
  2256. X    char *str;
  2257. X
  2258. X    str = malloc(6 + bytes + 2);   /* may need extra 2 bytes in do_run() */
  2259. X    *(char ***)str = Mlist;
  2260. X    str[4] = 1;
  2261. X    Mlist = (char **)str;
  2262. X    return (str + 5);
  2263. X}
  2264. X
  2265. Xstatic void
  2266. Xmpop_tobase()
  2267. X{
  2268. X    char *next;
  2269. X    while (Mlist) {
  2270. X        next = *Mlist;
  2271. X        if (((char *)Mlist)[4] == 0) {
  2272. X            free (Mlist);
  2273. X            Mlist = (char **)next;
  2274. X            break;
  2275. X        }
  2276. X        free (Mlist);
  2277. X        Mlist = (char **)next;
  2278. X    }
  2279. X}
  2280. X
  2281. X
  2282. X/*
  2283. X * Insert 'from' string in front of 'str' while deleting the
  2284. X * first entry in 'str'.  if freeok is set, then 'str' will be
  2285. X * free'd
  2286. X */
  2287. X
  2288. Xstatic char *
  2289. Xformat_insert_string(char *str, char *from)
  2290. X{
  2291. X    char *new1, *new2;
  2292. X    char *strskip;
  2293. X    int len;
  2294. X
  2295. X    for (strskip = str; *(signed char *)strskip>0 ||
  2296. X        *strskip && *strskip != HOT_BLANK 
  2297. X        && *strskip != HOT_SEMI && *strskip != HOT_PIPE
  2298. X        && *strskip != 0x80; ++strskip);
  2299. X    len = strlen(from);
  2300. X    new1 = malloc((len << 2) + 2);
  2301. X    preformat(from, new1);
  2302. X    len = strlen(new1) + strlen(strskip);
  2303. X    new2 = malloc(len+2);
  2304. X    strcpy(new2, new1);
  2305. X    strcat(new2, strskip);
  2306. X    new2[len+1] = 0;
  2307. X    free (new1);
  2308. X    free (str);
  2309. X    return new2;
  2310. X}
  2311. X
  2312. Xstatic int
  2313. Xcmd_stat( char *str )
  2314. X{
  2315. X    return (int)Command[find_command(str)].stat;
  2316. X}
  2317. X
  2318. Xchar *
  2319. Xfind_internal( char *str )
  2320. X{
  2321. X    return(Command[find_command(str)].name);
  2322. X}
  2323. X
  2324. Xstatic int
  2325. Xfind_command( char *str )
  2326. X{
  2327. X    int i, len = strlen(str);
  2328. X    struct COMMAND *com;
  2329. X    char c=*str;
  2330. X
  2331. X    for( com=Command, i=0; com->func; com++, i++ )
  2332. X        if ( c==*com->name && !strncmp(str, com->name, len))
  2333. X            return i;
  2334. X    return 0;
  2335. X}
  2336. X
  2337. Xint exec_fn_err;
  2338. X
  2339. Xextern struct FUNCTION {
  2340. X    short id, minargs, maxargs;
  2341. X    char *name;
  2342. X} Function[];
  2343. X
  2344. X
  2345. Xchar *gotfunc( int i, char **fav, int fac );
  2346. X
  2347. Xchar *
  2348. Xexec_function( char *str, char **fav, int fac)
  2349. X{
  2350. X    int len=strlen(str)-1, i;
  2351. X
  2352. X    exec_fn_err=0;
  2353. X    for (i = 0; Command[i].func; ++i)
  2354. X        if ( Command[i].stat&ST_FUNC && !strncmp(str,Command[i].name,len)) {
  2355. X            if( fac<Command[i].minargs ) {
  2356. X                exec_fn_err=20;
  2357. X                return NULL;
  2358. X            } else {
  2359. X                int (*func)( void )=Command[i].func;
  2360. X                char **oldav=av;
  2361. X                int  oldac=ac;
  2362. X                av=fav-1, ac=fac+1;
  2363. X                exec_fn_err=(*func)();
  2364. X                av=oldav, ac=oldac;
  2365. X                return get_var( LEVEL_SET, fav[0] );
  2366. X            }
  2367. X        }
  2368. X    for (i = 0; Function[i].id; ++i)
  2369. X        if ( len==strlen(Function[i].name)&&!strncmp(str,Function[i].name,len))
  2370. X            return gotfunc( i,fav,fac );
  2371. X
  2372. X    exec_fn_err=-1;
  2373. X    return NULL;
  2374. X}
  2375. X
  2376. Xint
  2377. Xechofunc(void)
  2378. X{
  2379. X    int  i;
  2380. X    char *str;
  2381. X
  2382. X    if( !strlen(av[0]) ) return -1;
  2383. X    exec_fn_err=0;
  2384. X    for (i = 0; Function[i].id; ++i)
  2385. X        if ( !strcmp(av[0],Function[i].name)) {
  2386. X            if(str=gotfunc( i,av,ac ))
  2387. X                printf("%s\n",str);
  2388. X            return exec_fn_err;
  2389. X        }
  2390. X    return -1;
  2391. X}
  2392. X
  2393. X
  2394. Xchar *
  2395. Xgotfunc( int i, char **fav, int fac )
  2396. X{
  2397. X    fac--; fav++;
  2398. X    if( fac<Function[i].minargs ) {
  2399. X        fprintf( stderr, "Not enough arguments for @%s\n",
  2400. X                          Function[i].name );
  2401. X        exec_fn_err=20;
  2402. X        return NULL;
  2403. X    } else if( fac>Function[i].maxargs ) {
  2404. X        if( ac > Function[i].maxargs )
  2405. X            fprintf( stderr, "Too many arguments for @%s\n",
  2406. X                              Function[i].name );
  2407. X        exec_fn_err=20;
  2408. X        return NULL;
  2409. X    } else {
  2410. X        exec_fn_err=dofunc( Function[i].id, fav, fac);
  2411. X        return get_var( LEVEL_SET, v_value );
  2412. X    }
  2413. X    return NULL;
  2414. X}
  2415. X
  2416. X
  2417. X
  2418. Xdo_help()
  2419. X{
  2420. X    struct COMMAND *com;
  2421. X    int i=0;
  2422. X
  2423. X    for (com = &Command[1]; com->func; ++com) {
  2424. X        printf ("%-12s", com->name);
  2425. X        if (++i % 6 == 0) printf("\n");
  2426. X    }
  2427. X    printf("\n\nUse   man <command>   for more information\n");
  2428. X    return 0;
  2429. X}
  2430. X
  2431. Xstatic char *
  2432. Xpush_cpy(s)
  2433. Xchar *s;
  2434. X{
  2435. X    return strcpy(mpush(strlen(s)), s);
  2436. X}
  2437. X
  2438. Xvoid
  2439. Xexec_every(void)
  2440. X{
  2441. X    char *str = get_var(LEVEL_SET, v_every);
  2442. X
  2443. X    if (str) {
  2444. X        ++H_stack, ++E_stack;
  2445. X        a0tospace( str );
  2446. X        exec_command(str);
  2447. X        --E_stack, --H_stack;
  2448. X    }
  2449. X}
  2450. X
  2451. Xchar *
  2452. Xa0tospace( str )
  2453. X    char *str;
  2454. X{
  2455. X    char *get=str, *put=str;
  2456. X
  2457. X    while( *get )
  2458. X        if( *get==0xA0 )
  2459. X            *put++=' ', get++;
  2460. X        else 
  2461. X            *put++=*get++;
  2462. X    return str;
  2463. X}
  2464. X
  2465. Xvoid
  2466. Xshow_usage( str )
  2467. X    char *str;
  2468. X{
  2469. X    int ccno, first=0, err=0;
  2470. X    char *get, *put, buf[300];
  2471. X
  2472. X    if( !str )
  2473. X        str=LastCommand, err=1;
  2474. X    for( put=str; *put && (*put&127)!=32; put++ ) ;
  2475. X    *put=0;
  2476. X
  2477. X    put=buf;
  2478. X    ccno = find_command (str);
  2479. X    if( get= Command[ccno].usage ) {
  2480. X        do {
  2481. X            put+=sprintf(put, first++?"       %s ":"Usage: %s ",
  2482. X                         Command[ccno].name );
  2483. X            if( *get=='-' ) {
  2484. X                *put++='['; *put++='-';
  2485. X                get++;
  2486. X                while( *get && *get!=' ' && *get!=',' )
  2487. X                    *put++=*get++;
  2488. X                *put++=']';
  2489. X            }
  2490. X            while( *get && *get!=','  )
  2491. X                *put++=*get++;
  2492. X            *put++='\n';
  2493. X        } while( *get++ );
  2494. X        *put=0;
  2495. X        fprintf( err ? stderr : stdout, "%s", buf );
  2496. X    }
  2497. X}
  2498. X
  2499. Xint
  2500. Xexecute( char *str )
  2501. X{
  2502. X    char  **tav=av, telast=elast;
  2503. X    int   tac=ac;
  2504. X    ULONG toptions=options;
  2505. X    int   thas_wild=has_wild;
  2506. X
  2507. X    if( !str ) return -1;
  2508. X
  2509. X    ++H_stack;
  2510. X    exec_command(str);
  2511. X    --H_stack;
  2512. X
  2513. X    av=tav; ac=tac; elast=telast; options=toptions; has_wild=thas_wild;
  2514. X
  2515. X    return 0;
  2516. X}
  2517. X
  2518. Xdo_exec( char *str )
  2519. X{
  2520. X    return execute( next_word( str ) );
  2521. X}
  2522. X
  2523. Xint
  2524. Xinteractive( void )
  2525. X{
  2526. X    return IsInteractive(Output());
  2527. X}
  2528. X
  2529. Xstatic int
  2530. Xcheckav( int n )
  2531. X{
  2532. X    char **tmp;
  2533. X    int newac;
  2534. X
  2535. X    if( ac+n+10>=max_ac ) {
  2536. X        newac=max_ac+n+40;
  2537. X        if( tmp=(char **)malloc(newac*sizeof(char *))) {
  2538. X            memcpy(tmp,av,max_ac*sizeof(char *));
  2539. X            free(av);
  2540. X            av=tmp; max_ac=newac;
  2541. X        } else 
  2542. X            return 1;
  2543. X    }
  2544. X    return 0;
  2545. X}
  2546. X
  2547. X/*    Parse the options specified in sw[]
  2548. X    Setting a bit in global variable options
  2549. X    for each one found
  2550. X*/
  2551. X
  2552. Xstatic void
  2553. Xget_opt( char **av, int *ac, int ccno )
  2554. X{
  2555. X    char **get=av+1,**put=av+1, *c, *s;
  2556. X    int i=1, l, usage=0, nac;
  2557. X    long oldopts;
  2558. X
  2559. X    options=0;
  2560. X    if( !ccno )
  2561. X        return;
  2562. X
  2563. X    for( ; i<*ac && *av[i]=='-'; i++, get++ ) {
  2564. X        if( !*(c=*get+1) )
  2565. X            goto stop;
  2566. X        oldopts=options;
  2567. X        for ( ; *c ; c++) {
  2568. X            if( *c<'a' || *c>'z' ) 
  2569. X                { options=oldopts; goto stop; }
  2570. X            for( l=0, s=Command[ccno].options; *s && *s != *c; ++s )
  2571. X                ++l;
  2572. X            if ( *s )
  2573. X                options |= (1 << l);
  2574. X            else if( !usage ) {
  2575. X                usage=1;
  2576. X                show_usage(NULL);
  2577. X            }
  2578. X        }
  2579. X    }
  2580. Xstop:
  2581. X    for( nac=1; i<*ac; i++ )
  2582. X        *put++=*get++, nac++;
  2583. X    *put=NULL;
  2584. X    *ac=nac;
  2585. X}
  2586. X
  2587. X#if 0
  2588. XUSHORT Options[160];
  2589. X
  2590. Xint
  2591. Xdo_options()
  2592. X{
  2593. X    for( i=1; i<ac; i+=2 ) {
  2594. X        if( ac-i<=1 )
  2595. X            { ierror( av[i], 500 ); return 20; }
  2596. X        if( *av[i+1]!='-' )
  2597. X            { ierror( av[i+1], 500 ); return 20; }
  2598. X        options=0;
  2599. X        parseopts( av[i+1]+1 );
  2600. X    }
  2601. X}
  2602. X#endif
  2603. END_OF_FILE
  2604. if test 30651 -ne `wc -c <'execom.c'`; then
  2605.     echo shar: \"'execom.c'\" unpacked with wrong size!
  2606. fi
  2607. # end of 'execom.c'
  2608. fi
  2609. echo shar: End of archive 4 \(of 6\).
  2610. cp /dev/null ark4isdone
  2611. MISSING=""
  2612. for I in 1 2 3 4 5 6 ; do
  2613.     if test ! -f ark${I}isdone ; then
  2614.     MISSING="${MISSING} ${I}"
  2615.     fi
  2616. done
  2617. if test "${MISSING}" = "" ; then
  2618.     echo You have unpacked all 6 archives.
  2619.     rm -f ark[1-9]isdone
  2620. else
  2621.     echo You still need to unpack the following archives:
  2622.     echo "        " ${MISSING}
  2623. fi
  2624. ##  End of shell archive.
  2625. exit 0
  2626. -- 
  2627. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2628. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2629. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2630.